summaryrefslogtreecommitdiff
path: root/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins')
-rw-r--r--source/Plugins/ABI/CMakeLists.txt13
-rw-r--r--source/Plugins/ABI/MacOSX-arm/CMakeLists.txt11
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/MacOSX-i386/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-arm/CMakeLists.txt11
-rw-r--r--source/Plugins/ABI/SysV-arm64/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-hexagon/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-i386/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-mips/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-mips64/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-ppc/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-ppc64/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-s390x/CMakeLists.txt10
-rw-r--r--source/Plugins/ABI/SysV-x86_64/CMakeLists.txt10
-rw-r--r--source/Plugins/Architecture/Arm/CMakeLists.txt11
-rw-r--r--source/Plugins/Architecture/CMakeLists.txt3
-rw-r--r--source/Plugins/Architecture/Mips/CMakeLists.txt10
-rw-r--r--source/Plugins/Architecture/PPC64/CMakeLists.txt11
-rw-r--r--source/Plugins/CMakeLists.txt22
-rw-r--r--source/Plugins/Disassembler/CMakeLists.txt1
-rw-r--r--source/Plugins/Disassembler/llvm/CMakeLists.txt14
-rw-r--r--source/Plugins/DynamicLoader/CMakeLists.txt6
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt13
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp1583
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h307
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/CMakeLists.txt10
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt16
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp1143
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h241
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp548
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h118
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp1207
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h182
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt15
-rw-r--r--source/Plugins/DynamicLoader/Static/CMakeLists.txt10
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/CMakeLists.txt9
-rw-r--r--source/Plugins/ExpressionParser/CMakeLists.txt1
-rw-r--r--source/Plugins/ExpressionParser/Clang/CMakeLists.txt50
-rw-r--r--source/Plugins/Instruction/ARM/CMakeLists.txt14
-rw-r--r--source/Plugins/Instruction/ARM64/CMakeLists.txt11
-rw-r--r--source/Plugins/Instruction/CMakeLists.txt5
-rw-r--r--source/Plugins/Instruction/MIPS/CMakeLists.txt18
-rw-r--r--source/Plugins/Instruction/MIPS64/CMakeLists.txt18
-rw-r--r--source/Plugins/Instruction/PPC64/CMakeLists.txt11
-rw-r--r--source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt13
-rw-r--r--source/Plugins/InstrumentationRuntime/CMakeLists.txt4
-rw-r--r--source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt13
-rw-r--r--source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt12
-rw-r--r--source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt13
-rw-r--r--source/Plugins/JITLoader/CMakeLists.txt1
-rw-r--r--source/Plugins/JITLoader/GDB/CMakeLists.txt14
-rw-r--r--source/Plugins/Language/CMakeLists.txt4
-rw-r--r--source/Plugins/Language/CPlusPlus/CMakeLists.txt34
-rw-r--r--source/Plugins/Language/ClangCommon/CMakeLists.txt9
-rw-r--r--source/Plugins/Language/ObjC/CMakeLists.txt37
-rw-r--r--source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt8
-rw-r--r--source/Plugins/LanguageRuntime/CMakeLists.txt3
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt2
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt10
-rw-r--r--source/Plugins/LanguageRuntime/Go/CMakeLists.txt11
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt24
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt1
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/CMakeLists.txt1
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt30
-rw-r--r--source/Plugins/MemoryHistory/CMakeLists.txt1
-rw-r--r--source/Plugins/MemoryHistory/asan/CMakeLists.txt9
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/CMakeLists.txt10
-rw-r--r--source/Plugins/ObjectContainer/CMakeLists.txt2
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/CMakeLists.txt10
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp238
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h82
-rw-r--r--source/Plugins/ObjectFile/Breakpad/CMakeLists.txt11
-rw-r--r--source/Plugins/ObjectFile/CMakeLists.txt5
-rw-r--r--source/Plugins/ObjectFile/ELF/CMakeLists.txt14
-rw-r--r--source/Plugins/ObjectFile/JIT/CMakeLists.txt11
-rw-r--r--source/Plugins/ObjectFile/Mach-O/CMakeLists.txt13
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp6380
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h220
-rw-r--r--source/Plugins/ObjectFile/PECOFF/CMakeLists.txt13
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp1183
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h294
-rw-r--r--source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp59
-rw-r--r--source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h23
-rw-r--r--source/Plugins/OperatingSystem/CMakeLists.txt1
-rw-r--r--source/Plugins/OperatingSystem/Python/CMakeLists.txt10
-rw-r--r--source/Plugins/Platform/Android/AdbClient.cpp653
-rw-r--r--source/Plugins/Platform/Android/AdbClient.h141
-rw-r--r--source/Plugins/Platform/Android/CMakeLists.txt13
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.cpp398
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.h91
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp232
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h64
-rw-r--r--source/Plugins/Platform/CMakeLists.txt18
-rw-r--r--source/Plugins/Platform/FreeBSD/CMakeLists.txt9
-rw-r--r--source/Plugins/Platform/Kalimba/CMakeLists.txt8
-rw-r--r--source/Plugins/Platform/Kalimba/PlatformKalimba.cpp154
-rw-r--r--source/Plugins/Platform/Kalimba/PlatformKalimba.h75
-rw-r--r--source/Plugins/Platform/Linux/CMakeLists.txt11
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.cpp408
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.h74
-rw-r--r--source/Plugins/Platform/MacOSX/CMakeLists.txt46
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp265
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h68
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp393
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h95
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp394
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h95
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.cpp1757
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.h141
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp872
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h208
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp343
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformMacOSX.h88
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp186
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h73
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp246
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h73
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp303
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h78
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp661
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h112
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp161
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h72
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp423
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h95
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt17
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h221
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm634
-rw-r--r--source/Plugins/Platform/NetBSD/CMakeLists.txt9
-rw-r--r--source/Plugins/Platform/OpenBSD/CMakeLists.txt9
-rw-r--r--source/Plugins/Platform/POSIX/CMakeLists.txt10
-rw-r--r--source/Plugins/Platform/Windows/CMakeLists.txt9
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.cpp593
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.h133
-rw-r--r--source/Plugins/Platform/gdb-server/CMakeLists.txt10
-rw-r--r--source/Plugins/Process/CMakeLists.txt19
-rw-r--r--source/Plugins/Process/FreeBSD/CMakeLists.txt24
-rw-r--r--source/Plugins/Process/Linux/CMakeLists.txt24
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp2097
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h261
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp196
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.h85
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp975
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h169
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp985
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h169
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp1053
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h140
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp804
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h149
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp638
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h115
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp1213
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h149
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp451
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.h119
-rw-r--r--source/Plugins/Process/Linux/ProcessorTrace.cpp395
-rw-r--r--source/Plugins/Process/Linux/ProcessorTrace.h141
-rw-r--r--source/Plugins/Process/Linux/Procfs.h31
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.cpp182
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.h57
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt22
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp1289
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h260
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp1037
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h220
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp35
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h43
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp147
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h44
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp148
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h45
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp115
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h39
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp118
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h39
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp170
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h77
-rw-r--r--source/Plugins/Process/NetBSD/CMakeLists.txt16
-rw-r--r--source/Plugins/Process/POSIX/CMakeLists.txt10
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt64
-rw-r--r--source/Plugins/Process/Windows/Common/CMakeLists.txt33
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.cpp520
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.h106
-rw-r--r--source/Plugins/Process/Windows/Common/ExceptionRecord.h80
-rw-r--r--source/Plugins/Process/Windows/Common/ForwardDecl.h42
-rw-r--r--source/Plugins/Process/Windows/Common/IDebugDelegate.h46
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp73
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.h67
-rw-r--r--source/Plugins/Process/Windows/Common/NtStructures.h31
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.cpp1119
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.h121
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp41
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.h36
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp136
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.h67
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp147
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.h50
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp341
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h48
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp287
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h52
-rw-r--r--source/Plugins/Process/elf-core/CMakeLists.txt22
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt42
-rw-r--r--source/Plugins/Process/mach-core/CMakeLists.txt17
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp635
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.h149
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp103
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.h70
-rw-r--r--source/Plugins/Process/minidump/CMakeLists.txt19
-rw-r--r--source/Plugins/ScriptInterpreter/CMakeLists.txt4
-rw-r--r--source/Plugins/ScriptInterpreter/None/CMakeLists.txt7
-rw-r--r--source/Plugins/ScriptInterpreter/Python/CMakeLists.txt28
-rw-r--r--source/Plugins/StructuredData/CMakeLists.txt2
-rw-r--r--source/Plugins/StructuredData/DarwinLog/CMakeLists.txt10
-rw-r--r--source/Plugins/SymbolFile/Breakpad/CMakeLists.txt12
-rw-r--r--source/Plugins/SymbolFile/CMakeLists.txt5
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt55
-rw-r--r--source/Plugins/SymbolFile/NativePDB/CMakeLists.txt21
-rw-r--r--source/Plugins/SymbolFile/PDB/CMakeLists.txt16
-rw-r--r--source/Plugins/SymbolFile/Symtab/CMakeLists.txt7
-rw-r--r--source/Plugins/SymbolVendor/CMakeLists.txt5
-rw-r--r--source/Plugins/SymbolVendor/ELF/CMakeLists.txt8
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt10
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp321
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h51
-rw-r--r--source/Plugins/SystemRuntime/CMakeLists.txt1
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp398
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h115
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp406
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h120
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp403
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h112
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp410
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h114
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt17
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp1021
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h299
-rw-r--r--source/Plugins/UnwindAssembly/CMakeLists.txt2
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/CMakeLists.txt8
-rw-r--r--source/Plugins/UnwindAssembly/x86/CMakeLists.txt14
241 files changed, 0 insertions, 48909 deletions
diff --git a/source/Plugins/ABI/CMakeLists.txt b/source/Plugins/ABI/CMakeLists.txt
deleted file mode 100644
index 9d7a79308d7b9..0000000000000
--- a/source/Plugins/ABI/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_subdirectory(SysV-arm)
-add_subdirectory(SysV-arm64)
-add_subdirectory(SysV-hexagon)
-add_subdirectory(SysV-ppc)
-add_subdirectory(SysV-ppc64)
-add_subdirectory(SysV-mips)
-add_subdirectory(SysV-mips64)
-add_subdirectory(SysV-s390x)
-add_subdirectory(SysV-i386)
-add_subdirectory(SysV-x86_64)
-add_subdirectory(MacOSX-i386)
-add_subdirectory(MacOSX-arm)
-add_subdirectory(MacOSX-arm64)
diff --git a/source/Plugins/ABI/MacOSX-arm/CMakeLists.txt b/source/Plugins/ABI/MacOSX-arm/CMakeLists.txt
deleted file mode 100644
index b41814f3237b5..0000000000000
--- a/source/Plugins/ABI/MacOSX-arm/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginABIMacOSX_arm PLUGIN
- ABIMacOSX_arm.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt b/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt
deleted file mode 100644
index f769d63bcdacf..0000000000000
--- a/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABIMacOSX_arm64 PLUGIN
- ABIMacOSX_arm64.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/MacOSX-i386/CMakeLists.txt b/source/Plugins/ABI/MacOSX-i386/CMakeLists.txt
deleted file mode 100644
index 21f153d36e084..0000000000000
--- a/source/Plugins/ABI/MacOSX-i386/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABIMacOSX_i386 PLUGIN
- ABIMacOSX_i386.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-arm/CMakeLists.txt b/source/Plugins/ABI/SysV-arm/CMakeLists.txt
deleted file mode 100644
index c5979046d36cb..0000000000000
--- a/source/Plugins/ABI/SysV-arm/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginABISysV_arm PLUGIN
- ABISysV_arm.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-arm64/CMakeLists.txt b/source/Plugins/ABI/SysV-arm64/CMakeLists.txt
deleted file mode 100644
index 077b394823c6d..0000000000000
--- a/source/Plugins/ABI/SysV-arm64/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_arm64 PLUGIN
- ABISysV_arm64.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-hexagon/CMakeLists.txt b/source/Plugins/ABI/SysV-hexagon/CMakeLists.txt
deleted file mode 100644
index a857fff12399e..0000000000000
--- a/source/Plugins/ABI/SysV-hexagon/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_hexagon PLUGIN
- ABISysV_hexagon.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-i386/CMakeLists.txt b/source/Plugins/ABI/SysV-i386/CMakeLists.txt
deleted file mode 100644
index 598b3d03c0f39..0000000000000
--- a/source/Plugins/ABI/SysV-i386/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_i386 PLUGIN
- ABISysV_i386.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-mips/CMakeLists.txt b/source/Plugins/ABI/SysV-mips/CMakeLists.txt
deleted file mode 100644
index a3266a75ae738..0000000000000
--- a/source/Plugins/ABI/SysV-mips/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_mips PLUGIN
- ABISysV_mips.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-mips64/CMakeLists.txt b/source/Plugins/ABI/SysV-mips64/CMakeLists.txt
deleted file mode 100644
index 5eddfb539f051..0000000000000
--- a/source/Plugins/ABI/SysV-mips64/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_mips64 PLUGIN
- ABISysV_mips64.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-ppc/CMakeLists.txt b/source/Plugins/ABI/SysV-ppc/CMakeLists.txt
deleted file mode 100644
index 63bfc4a96cdf4..0000000000000
--- a/source/Plugins/ABI/SysV-ppc/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_ppc PLUGIN
- ABISysV_ppc.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt b/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt
deleted file mode 100644
index b31182dd0f78e..0000000000000
--- a/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_ppc64 PLUGIN
- ABISysV_ppc64.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-s390x/CMakeLists.txt b/source/Plugins/ABI/SysV-s390x/CMakeLists.txt
deleted file mode 100644
index f670f0157a6be..0000000000000
--- a/source/Plugins/ABI/SysV-s390x/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_s390x PLUGIN
- ABISysV_s390x.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ABI/SysV-x86_64/CMakeLists.txt b/source/Plugins/ABI/SysV-x86_64/CMakeLists.txt
deleted file mode 100644
index 17644d74ac2f3..0000000000000
--- a/source/Plugins/ABI/SysV-x86_64/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginABISysV_x86_64 PLUGIN
- ABISysV_x86_64.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Architecture/Arm/CMakeLists.txt b/source/Plugins/Architecture/Arm/CMakeLists.txt
deleted file mode 100644
index 60bbe69a99fbf..0000000000000
--- a/source/Plugins/Architecture/Arm/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginArchitectureArm PLUGIN
- ArchitectureArm.cpp
-
- LINK_LIBS
- lldbPluginProcessUtility
- lldbCore
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Architecture/CMakeLists.txt b/source/Plugins/Architecture/CMakeLists.txt
deleted file mode 100644
index 14ad91644595a..0000000000000
--- a/source/Plugins/Architecture/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_subdirectory(Arm)
-add_subdirectory(Mips)
-add_subdirectory(PPC64)
diff --git a/source/Plugins/Architecture/Mips/CMakeLists.txt b/source/Plugins/Architecture/Mips/CMakeLists.txt
deleted file mode 100644
index 9734edc6b12bb..0000000000000
--- a/source/Plugins/Architecture/Mips/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginArchitectureMips PLUGIN
- ArchitectureMips.cpp
-
- LINK_LIBS
- lldbCore
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Architecture/PPC64/CMakeLists.txt b/source/Plugins/Architecture/PPC64/CMakeLists.txt
deleted file mode 100644
index 2cba112cf8827..0000000000000
--- a/source/Plugins/Architecture/PPC64/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginArchitecturePPC64 PLUGIN
- ArchitecturePPC64.cpp
-
- LINK_LIBS
- lldbPluginProcessUtility
- lldbCore
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/CMakeLists.txt b/source/Plugins/CMakeLists.txt
deleted file mode 100644
index 5092b210a12cf..0000000000000
--- a/source/Plugins/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-add_subdirectory(ABI)
-add_subdirectory(Architecture)
-add_subdirectory(Disassembler)
-add_subdirectory(DynamicLoader)
-add_subdirectory(ExpressionParser)
-add_subdirectory(Instruction)
-add_subdirectory(InstrumentationRuntime)
-add_subdirectory(JITLoader)
-add_subdirectory(Language)
-add_subdirectory(LanguageRuntime)
-add_subdirectory(MemoryHistory)
-add_subdirectory(ObjectContainer)
-add_subdirectory(ObjectFile)
-add_subdirectory(OperatingSystem)
-add_subdirectory(Platform)
-add_subdirectory(Process)
-add_subdirectory(ScriptInterpreter)
-add_subdirectory(StructuredData)
-add_subdirectory(SymbolFile)
-add_subdirectory(SystemRuntime)
-add_subdirectory(SymbolVendor)
-add_subdirectory(UnwindAssembly)
diff --git a/source/Plugins/Disassembler/CMakeLists.txt b/source/Plugins/Disassembler/CMakeLists.txt
deleted file mode 100644
index 6e3c904d5a605..0000000000000
--- a/source/Plugins/Disassembler/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(llvm)
diff --git a/source/Plugins/Disassembler/llvm/CMakeLists.txt b/source/Plugins/Disassembler/llvm/CMakeLists.txt
deleted file mode 100644
index a25a436d498e1..0000000000000
--- a/source/Plugins/Disassembler/llvm/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-add_lldb_library(lldbPluginDisassemblerLLVM PLUGIN
- DisassemblerLLVMC.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- ${LLVM_TARGETS_TO_BUILD}
- MC
- MCDisassembler
- RuntimeDyld
- Support
- )
diff --git a/source/Plugins/DynamicLoader/CMakeLists.txt b/source/Plugins/DynamicLoader/CMakeLists.txt
deleted file mode 100644
index 9f3b2ab0e50fd..0000000000000
--- a/source/Plugins/DynamicLoader/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-add_subdirectory(Darwin-Kernel)
-add_subdirectory(MacOSX-DYLD)
-add_subdirectory(POSIX-DYLD)
-add_subdirectory(Static)
-add_subdirectory(Hexagon-DYLD)
-add_subdirectory(Windows-DYLD)
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt b/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt
deleted file mode 100644
index ffc797b7475bf..0000000000000
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginDynamicLoaderDarwinKernel PLUGIN
- DynamicLoaderDarwinKernel.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginPlatformMacOSX
- )
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
deleted file mode 100644
index 3a80c68dd4d71..0000000000000
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ /dev/null
@@ -1,1583 +0,0 @@
-//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Core/StreamFile.h"
-#include "lldb/Host/Symbols.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/OperatingSystem.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-
-#include "DynamicLoaderDarwinKernel.h"
-
-//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
-#ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-// Progressively greater amounts of scanning we will allow For some targets
-// very early in startup, we can't do any random reads of memory or we can
-// crash the device so a setting is needed that can completely disable the
-// KASLR scans.
-
-enum KASLRScanType {
- eKASLRScanNone = 0, // No reading into the inferior at all
- eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel
- // addr, then see if a kernel is there
- eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel;
- // checking at 96 locations total
- eKASLRScanExhaustiveScan // Scan through the entire possible kernel address
- // range looking for a kernel
-};
-
-static constexpr OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
- {eKASLRScanNone, "none",
- "Do not read memory looking for a Darwin kernel when attaching."},
- {eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load "
- "addr in the lowglo page "
- "(boot-args=debug) only."},
- {eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find "
- "the Darwin kernel's load address."},
- {eKASLRScanExhaustiveScan, "exhaustive-scan",
- "Scan through the entire potential address range of Darwin kernel (only "
- "on 32-bit targets)."}};
-
-static constexpr PropertyDefinition g_properties[] = {
- {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, {},
- "Automatically loads kext images when attaching to a kernel."},
- {"scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL,
- OptionEnumValues(g_kaslr_kernel_scan_enum_values),
- "Control how many reads lldb will make while searching for a Darwin "
- "kernel on attach."}};
-
-enum { ePropertyLoadKexts, ePropertyScanType };
-
-class DynamicLoaderDarwinKernelProperties : public Properties {
-public:
- static ConstString &GetSettingName() {
- static ConstString g_setting_name("darwin-kernel");
- return g_setting_name;
- }
-
- DynamicLoaderDarwinKernelProperties() : Properties() {
- m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual ~DynamicLoaderDarwinKernelProperties() {}
-
- bool GetLoadKexts() const {
- const uint32_t idx = ePropertyLoadKexts;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(
- NULL, idx, g_properties[idx].default_uint_value != 0);
- }
-
- KASLRScanType GetScanType() const {
- const uint32_t idx = ePropertyScanType;
- return (KASLRScanType)m_collection_sp->GetPropertyAtIndexAsEnumeration(
- NULL, idx, g_properties[idx].default_uint_value);
- }
-};
-
-typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties>
- DynamicLoaderDarwinKernelPropertiesSP;
-
-static const DynamicLoaderDarwinKernelPropertiesSP &GetGlobalProperties() {
- static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset(new DynamicLoaderDarwinKernelProperties());
- return g_settings_sp;
-}
-
-//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into the plugin
-// info class that gets handed out by the plugin factory and allows the lldb to
-// instantiate an instance of this class.
-//----------------------------------------------------------------------
-DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
- bool force) {
- if (!force) {
- // If the user provided an executable binary and it is not a kernel, this
- // plugin should not create an instance.
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module) {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file) {
- if (object_file->GetStrata() != ObjectFile::eStrataKernel) {
- return NULL;
- }
- }
- }
-
- // If the target's architecture does not look like an Apple environment,
- // this plugin should not create an instance.
- const llvm::Triple &triple_ref =
- process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS()) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
- if (triple_ref.getVendor() != llvm::Triple::Apple) {
- return NULL;
- }
- break;
- // If we have triple like armv7-unknown-unknown, we should try looking for
- // a Darwin kernel.
- case llvm::Triple::UnknownOS:
- break;
- default:
- return NULL;
- break;
- }
- }
-
- // At this point if there is an ExecutableModule, it is a kernel and the
- // Target is some variant of an Apple system. If the Process hasn't provided
- // the kernel load address, we need to look around in memory to find it.
-
- const addr_t kernel_load_address = SearchForDarwinKernel(process);
- if (CheckForKernelImageAtAddress(kernel_load_address, process).IsValid()) {
- process->SetCanRunCode(false);
- return new DynamicLoaderDarwinKernel(process, kernel_load_address);
- }
- return NULL;
-}
-
-lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
- addr_t kernel_load_address = process->GetImageInfoAddress();
- if (kernel_load_address == LLDB_INVALID_ADDRESS) {
- kernel_load_address = SearchForKernelAtSameLoadAddr(process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS) {
- kernel_load_address = SearchForKernelWithDebugHints(process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS) {
- kernel_load_address = SearchForKernelNearPC(process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS) {
- kernel_load_address = SearchForKernelViaExhaustiveSearch(process);
- }
- }
- }
- }
- return kernel_load_address;
-}
-
-//----------------------------------------------------------------------
-// Check if the kernel binary is loaded in memory without a slide. First verify
-// that the ExecutableModule is a kernel before we proceed. Returns the address
-// of the kernel if one was found, else LLDB_INVALID_ADDRESS.
-//----------------------------------------------------------------------
-lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module == NULL)
- return LLDB_INVALID_ADDRESS;
-
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- if (exe_objfile == NULL)
- return LLDB_INVALID_ADDRESS;
-
- if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
- exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
- return LLDB_INVALID_ADDRESS;
-
- if (!exe_objfile->GetBaseAddress().IsValid())
- return LLDB_INVALID_ADDRESS;
-
- if (CheckForKernelImageAtAddress(
- exe_objfile->GetBaseAddress().GetFileAddress(), process) ==
- exe_module->GetUUID())
- return exe_objfile->GetBaseAddress().GetFileAddress();
-
- return LLDB_INVALID_ADDRESS;
-}
-
-//----------------------------------------------------------------------
-// If the debug flag is included in the boot-args nvram setting, the kernel's
-// load address will be noted in the lowglo page at a fixed address Returns the
-// address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
-//----------------------------------------------------------------------
-lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
- if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
- return LLDB_INVALID_ADDRESS;
-
- Status read_err;
- addr_t kernel_addresses_64[] = {
- 0xfffffff000004010ULL, // newest arm64 devices
- 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
- 0xffffff8000002010ULL, // oldest arm64 devices
- LLDB_INVALID_ADDRESS};
- addr_t kernel_addresses_32[] = {0xffff0110, // 2016 and earlier armv7 devices
- 0xffff1010,
- LLDB_INVALID_ADDRESS};
-
- uint8_t uval[8];
- if (process->GetAddressByteSize() == 8) {
- for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
- if (process->ReadMemoryFromInferior (kernel_addresses_64[i], uval, 8, read_err) == 8)
- {
- DataExtractor data (&uval, 8, process->GetByteOrder(), process->GetAddressByteSize());
- offset_t offset = 0;
- uint64_t addr = data.GetU64 (&offset);
- if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
- return addr;
- }
- }
- }
- }
-
- if (process->GetAddressByteSize() == 4) {
- for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
- if (process->ReadMemoryFromInferior (kernel_addresses_32[i], uval, 4, read_err) == 4)
- {
- DataExtractor data (&uval, 4, process->GetByteOrder(), process->GetAddressByteSize());
- offset_t offset = 0;
- uint32_t addr = data.GetU32 (&offset);
- if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
- return addr;
- }
- }
- }
- }
-
- return LLDB_INVALID_ADDRESS;
-}
-
-//----------------------------------------------------------------------
-// If the kernel is currently executing when lldb attaches, and we don't have a
-// better way of finding the kernel's load address, try searching backwards
-// from the current pc value looking for the kernel's Mach header in memory.
-// Returns the address of the kernel if one was found, else
-// LLDB_INVALID_ADDRESS.
-//----------------------------------------------------------------------
-lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
- if (GetGlobalProperties()->GetScanType() == eKASLRScanNone ||
- GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses) {
- return LLDB_INVALID_ADDRESS;
- }
-
- ThreadSP thread = process->GetThreadList().GetSelectedThread();
- if (thread.get() == NULL)
- return LLDB_INVALID_ADDRESS;
- addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
-
- // The kernel is always loaded in high memory, if the top bit is zero,
- // this isn't a kernel.
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
- if ((pc & (1ULL << 63)) == 0) {
- return LLDB_INVALID_ADDRESS;
- }
- } else {
- if ((pc & (1ULL << 31)) == 0) {
- return LLDB_INVALID_ADDRESS;
- }
- }
-
- if (pc == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // The kernel will load at at one megabyte boundary (0x100000), or at that
- // boundary plus an offset of one page (0x1000) or two, or four (0x4000),
- // depending on the device.
-
- // Round the current pc down to the nearest one megabyte boundary - the place
- // where we will start searching.
- addr_t addr = pc & ~0xfffff;
-
- // Search backwards 32 megabytes, looking for the start of the kernel at each
- // one-megabyte boundary.
- for (int i = 0; i < 32; i++, addr -= 0x100000) {
- // x86_64 kernels are at offset 0
- if (CheckForKernelImageAtAddress(addr, process).IsValid())
- return addr;
- // 32-bit arm kernels are at offset 0x1000 (one 4k page)
- if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
- return addr + 0x1000;
- // 64-bit arm kernels are at offset 0x4000 (one 16k page)
- if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
- return addr + 0x4000;
- }
-
- return LLDB_INVALID_ADDRESS;
-}
-
-//----------------------------------------------------------------------
-// Scan through the valid address range for a kernel binary. This is uselessly
-// slow in 64-bit environments so we don't even try it. This scan is not
-// enabled by default even for 32-bit targets. Returns the address of the
-// kernel if one was found, else LLDB_INVALID_ADDRESS.
-//----------------------------------------------------------------------
-lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
- Process *process) {
- if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan) {
- return LLDB_INVALID_ADDRESS;
- }
-
- addr_t kernel_range_low, kernel_range_high;
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
- kernel_range_low = 1ULL << 63;
- kernel_range_high = UINT64_MAX;
- } else {
- kernel_range_low = 1ULL << 31;
- kernel_range_high = UINT32_MAX;
- }
-
- // Stepping through memory at one-megabyte resolution looking for a kernel
- // rarely works (fast enough) with a 64-bit address space -- for now, let's
- // not even bother. We may be attaching to something which *isn't* a kernel
- // and we don't want to spin for minutes on-end looking for a kernel.
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
- return LLDB_INVALID_ADDRESS;
-
- addr_t addr = kernel_range_low;
-
- while (addr >= kernel_range_low && addr < kernel_range_high) {
- // x86_64 kernels are at offset 0
- if (CheckForKernelImageAtAddress(addr, process).IsValid())
- return addr;
- // 32-bit arm kernels are at offset 0x1000 (one 4k page)
- if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
- return addr + 0x1000;
- // 64-bit arm kernels are at offset 0x4000 (one 16k page)
- if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
- return addr + 0x4000;
- addr += 0x100000;
- }
- return LLDB_INVALID_ADDRESS;
-}
-
-//----------------------------------------------------------------------
-// Read the mach_header struct out of memory and return it.
-// Returns true if the mach_header was successfully read,
-// Returns false if there was a problem reading the header, or it was not
-// a Mach-O header.
-//----------------------------------------------------------------------
-
-bool
-DynamicLoaderDarwinKernel::ReadMachHeader(addr_t addr, Process *process, llvm::MachO::mach_header &header) {
- Status read_error;
-
- // Read the mach header and see whether it looks like a kernel
- if (process->DoReadMemory (addr, &header, sizeof(header), read_error) !=
- sizeof(header))
- return false;
-
- const uint32_t magicks[] = { llvm::MachO::MH_MAGIC_64, llvm::MachO::MH_MAGIC, llvm::MachO::MH_CIGAM, llvm::MachO::MH_CIGAM_64};
-
- bool found_matching_pattern = false;
- for (size_t i = 0; i < llvm::array_lengthof (magicks); i++)
- if (::memcmp (&header.magic, &magicks[i], sizeof (uint32_t)) == 0)
- found_matching_pattern = true;
-
- if (!found_matching_pattern)
- 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);
- }
-
- return true;
-}
-
-//----------------------------------------------------------------------
-// Given an address in memory, look to see if there is a kernel image at that
-// address.
-// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
-// will be false.
-//----------------------------------------------------------------------
-lldb_private::UUID
-DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
- Process *process) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (addr == LLDB_INVALID_ADDRESS)
- return UUID();
-
- if (log)
- log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
- "looking for kernel binary at 0x%" PRIx64,
- addr);
-
- llvm::MachO::mach_header header;
-
- if (!ReadMachHeader(addr, process, header))
- return UUID();
-
- // First try a quick test -- read the first 4 bytes and see if there is a
- // valid Mach-O magic field there
- // (the first field of the mach_header/mach_header_64 struct).
- // A kernel is an executable which does not have the dynamic link object flag
- // set.
- if (header.filetype == llvm::MachO::MH_EXECUTE &&
- (header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
- // Create a full module to get the UUID
- ModuleSP memory_module_sp =
- process->ReadModuleFromMemory(FileSpec("temp_mach_kernel"), addr);
- if (!memory_module_sp.get())
- return UUID();
-
- ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
- if (exe_objfile == NULL) {
- if (log)
- log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress "
- "found a binary at 0x%" PRIx64
- " but could not create an object file from memory",
- addr);
- return UUID();
- }
-
- if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
- exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
- ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
- if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
- kernel_arch)) {
- process->GetTarget().SetArchitecture(kernel_arch);
- }
- if (log) {
- std::string uuid_str;
- if (memory_module_sp->GetUUID().IsValid()) {
- uuid_str = "with UUID ";
- uuid_str += memory_module_sp->GetUUID().GetAsString();
- } else {
- uuid_str = "and no LC_UUID found in load commands ";
- }
- log->Printf(
- "DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
- "kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",
- addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());
- }
- return memory_module_sp->GetUUID();
- }
- }
-
- return UUID();
-}
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
- lldb::addr_t kernel_addr)
- : DynamicLoader(process), m_kernel_load_address(kernel_addr), m_kernel(),
- m_kext_summary_header_ptr_addr(), m_kext_summary_header_addr(),
- m_kext_summary_header(), m_known_kexts(), m_mutex(),
- m_break_id(LLDB_INVALID_BREAK_ID) {
- Status error;
- PlatformSP platform_sp(
- Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
- // Only select the darwin-kernel Platform if we've been asked to load kexts.
- // It can take some time to scan over all of the kext info.plists and that
- // shouldn't be done if kext loading is explicitly disabled.
- if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
- process->GetTarget().SetPlatform(platform_sp);
- }
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() { Clear(true); }
-
-void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
- LoadKernelModuleIfNeeded();
- SetNotificationBreakpointIfNeeded();
-}
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void DynamicLoaderDarwinKernel::DidAttach() {
- PrivateInitialize(m_process);
- UpdateIfNeeded();
-}
-
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void DynamicLoaderDarwinKernel::DidLaunch() {
- PrivateInitialize(m_process);
- UpdateIfNeeded();
-}
-
-//----------------------------------------------------------------------
-// Clear out the state of this class.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwinKernel::Clear(bool clear_process) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
-
- if (clear_process)
- m_process = NULL;
- m_kernel.Clear();
- m_known_kexts.clear();
- m_kext_summary_header_ptr_addr.Clear();
- m_kext_summary_header_addr.Clear();
- m_break_id = LLDB_INVALID_BREAK_ID;
-}
-
-bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
- Process *process) {
- if (IsLoaded())
- return true;
-
- if (m_module_sp) {
- bool changed = false;
- if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
- m_load_process_stop_id = process->GetStopID();
- }
- return false;
-}
-
-void DynamicLoaderDarwinKernel::KextImageInfo::SetModule(ModuleSP module_sp) {
- m_module_sp = module_sp;
- if (module_sp.get() && module_sp->GetObjectFile()) {
- if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable &&
- module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) {
- m_kernel_image = true;
- } else {
- m_kernel_image = false;
- }
- }
-}
-
-ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
- return m_module_sp;
-}
-
-void DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress(
- addr_t load_addr) {
- m_load_address = load_addr;
-}
-
-addr_t DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress() const {
- return m_load_address;
-}
-
-uint64_t DynamicLoaderDarwinKernel::KextImageInfo::GetSize() const {
- return m_size;
-}
-
-void DynamicLoaderDarwinKernel::KextImageInfo::SetSize(uint64_t size) {
- m_size = size;
-}
-
-uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId() const {
- return m_load_process_stop_id;
-}
-
-void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
- uint32_t stop_id) {
- m_load_process_stop_id = stop_id;
-}
-
-bool DynamicLoaderDarwinKernel::KextImageInfo::
-operator==(const KextImageInfo &rhs) {
- if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
- return m_uuid == rhs.GetUUID();
- }
-
- return m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress();
-}
-
-void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
- m_name = name;
-}
-
-std::string DynamicLoaderDarwinKernel::KextImageInfo::GetName() const {
- return m_name;
-}
-
-void DynamicLoaderDarwinKernel::KextImageInfo::SetUUID(const UUID &uuid) {
- m_uuid = uuid;
-}
-
-UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
- return m_uuid;
-}
-
-// Given the m_load_address from the kext summaries, and a UUID, try to create
-// an in-memory Module at that address. Require that the MemoryModule have a
-// matching UUID and detect if this MemoryModule is a kernel or a kext.
-//
-// Returns true if m_memory_module_sp is now set to a valid Module.
-
-bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
- Process *process) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (m_memory_module_sp.get() != NULL)
- return true;
- if (m_load_address == LLDB_INVALID_ADDRESS)
- return false;
-
- FileSpec file_spec(m_name.c_str());
-
- llvm::MachO::mach_header mh;
- size_t size_to_read = 512;
- if (ReadMachHeader(m_load_address, process, mh)) {
- if (mh.magic == llvm::MachO::MH_CIGAM || mh.magic == llvm::MachO::MH_MAGIC)
- size_to_read = sizeof(llvm::MachO::mach_header) + mh.sizeofcmds;
- if (mh.magic == llvm::MachO::MH_CIGAM_64 ||
- mh.magic == llvm::MachO::MH_MAGIC_64)
- size_to_read = sizeof(llvm::MachO::mach_header_64) + mh.sizeofcmds;
- }
-
- ModuleSP memory_module_sp =
- process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read);
-
- if (memory_module_sp.get() == NULL)
- return false;
-
- bool is_kernel = false;
- if (memory_module_sp->GetObjectFile()) {
- if (memory_module_sp->GetObjectFile()->GetType() ==
- ObjectFile::eTypeExecutable &&
- memory_module_sp->GetObjectFile()->GetStrata() ==
- ObjectFile::eStrataKernel) {
- is_kernel = true;
- } else if (memory_module_sp->GetObjectFile()->GetType() ==
- ObjectFile::eTypeSharedLibrary) {
- is_kernel = false;
- }
- }
-
- // If this is a kext, and the kernel specified what UUID we should find at
- // this load address, require that the memory module have a matching UUID or
- // something has gone wrong and we should discard it.
- if (m_uuid.IsValid()) {
- if (m_uuid != memory_module_sp->GetUUID()) {
- if (log) {
- log->Printf("KextImageInfo::ReadMemoryModule the kernel said to find "
- "uuid %s at 0x%" PRIx64
- " but instead we found uuid %s, throwing it away",
- m_uuid.GetAsString().c_str(), m_load_address,
- memory_module_sp->GetUUID().GetAsString().c_str());
- }
- return false;
- }
- }
-
- // If the in-memory Module has a UUID, let's use that.
- if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) {
- m_uuid = memory_module_sp->GetUUID();
- }
-
- m_memory_module_sp = memory_module_sp;
- m_kernel_image = is_kernel;
- if (is_kernel) {
- if (log) {
- // This is unusual and probably not intended
- log->Printf("KextImageInfo::ReadMemoryModule read the kernel binary out "
- "of memory");
- }
- if (memory_module_sp->GetArchitecture().IsValid()) {
- process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
- }
- if (m_uuid.IsValid()) {
- ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
- if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid()) {
- if (m_uuid != exe_module_sp->GetUUID()) {
- // The user specified a kernel binary that has a different UUID than
- // the kernel actually running in memory. This never ends well;
- // clear the user specified kernel binary from the Target.
-
- m_module_sp.reset();
-
- ModuleList user_specified_kernel_list;
- user_specified_kernel_list.Append(exe_module_sp);
- process->GetTarget().GetImages().Remove(user_specified_kernel_list);
- }
- }
- }
- }
-
- return true;
-}
-
-bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
- return m_kernel_image;
-}
-
-void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
- m_kernel_image = is_kernel;
-}
-
-bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
- Process *process) {
- if (IsLoaded())
- return true;
-
- Target &target = process->GetTarget();
-
- // If we don't have / can't create a memory module for this kext, don't try
- // to load it - we won't have the correct segment load addresses.
- if (!ReadMemoryModule(process)) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64
- " to get the segment load addresses.",
- m_name.c_str(), m_load_address);
- return false;
- }
-
- bool uuid_is_valid = m_uuid.IsValid();
-
- if (IsKernel() && uuid_is_valid && m_memory_module_sp.get()) {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s) {
- s->Printf("Kernel UUID: %s\n",
- m_memory_module_sp->GetUUID().GetAsString().c_str());
- s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
- }
- }
-
- if (!m_module_sp) {
- // See if the kext has already been loaded into the target, probably by the
- // user doing target modules add.
- const ModuleList &target_images = target.GetImages();
- m_module_sp = target_images.FindModule(m_uuid);
-
- // Search for the kext on the local filesystem via the UUID
- if (!m_module_sp && uuid_is_valid) {
- ModuleSpec module_spec;
- module_spec.GetUUID() = m_uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
-
- // For the kernel, we really do need an on-disk file copy of the binary
- // to do anything useful. This will force a clal to
- if (IsKernel()) {
- if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
- if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
- m_module_sp.reset(new Module(module_spec.GetFileSpec(),
- target.GetArchitecture()));
- if (m_module_sp.get() &&
- m_module_sp->MatchesModuleSpec(module_spec)) {
- ModuleList loaded_module_list;
- loaded_module_list.Append(m_module_sp);
- target.ModulesDidLoad(loaded_module_list);
- }
- }
- }
- }
-
- // If the current platform is PlatformDarwinKernel, create a ModuleSpec
- // with the filename set to be the bundle ID for this kext, e.g.
- // "com.apple.filesystems.msdosfs", and ask the platform to find it.
- PlatformSP platform_sp(target.GetPlatform());
- if (!m_module_sp && platform_sp) {
- ConstString platform_name(platform_sp->GetPluginName());
- static ConstString g_platform_name(
- PlatformDarwinKernel::GetPluginNameStatic());
- if (platform_name == g_platform_name) {
- ModuleSpec kext_bundle_module_spec(module_spec);
- FileSpec kext_filespec(m_name.c_str());
- kext_bundle_module_spec.GetFileSpec() = kext_filespec;
- platform_sp->GetSharedModule(
- kext_bundle_module_spec, process, m_module_sp,
- &target.GetExecutableSearchPaths(), NULL, NULL);
- }
- }
-
- // Ask the Target to find this file on the local system, if possible.
- // This will search in the list of currently-loaded files, look in the
- // standard search paths on the system, and on a Mac it will try calling
- // the DebugSymbols framework with the UUID to find the binary via its
- // search methods.
- if (!m_module_sp) {
- m_module_sp = target.GetSharedModule(module_spec);
- }
-
- if (IsKernel() && !m_module_sp) {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s) {
- s->Printf("WARNING: Unable to locate kernel binary on the debugger "
- "system.\n");
- }
- }
- }
-
- // If we managed to find a module, append it to the target's list of
- // images. If we also have a memory module, require that they have matching
- // UUIDs
- if (m_module_sp) {
- bool uuid_match_ok = true;
- if (m_memory_module_sp) {
- if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID()) {
- uuid_match_ok = false;
- }
- }
- if (uuid_match_ok) {
- target.GetImages().AppendIfNeeded(m_module_sp);
- if (IsKernel() &&
- target.GetExecutableModulePointer() != m_module_sp.get()) {
- target.SetExecutableModule(m_module_sp, eLoadDependentsNo);
- }
- }
- }
- }
-
- if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty()) {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s) {
- s->Printf("warning: Can't find binary/dSYM for %s (%s)\n", m_name.c_str(),
- m_uuid.GetAsString().c_str());
- }
- }
-
- static ConstString g_section_name_LINKEDIT("__LINKEDIT");
-
- if (m_memory_module_sp && m_module_sp) {
- if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID()) {
- ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
- ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
-
- if (memory_object_file && ondisk_object_file) {
- // The memory_module for kexts may have an invalid __LINKEDIT seg; skip
- // it.
- const bool ignore_linkedit = !IsKernel();
-
- SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
- SectionList *memory_section_list = memory_object_file->GetSectionList();
- if (memory_section_list && ondisk_section_list) {
- const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
- // There may be CTF sections in the memory image so we can't always
- // just compare the number of sections (which are actually segments
- // in mach-o parlance)
- uint32_t sect_idx = 0;
-
- // Use the memory_module's addresses for each section to set the file
- // module's load address as appropriate. We don't want to use a
- // single slide value for the entire kext - different segments may be
- // slid different amounts by the kext loader.
-
- uint32_t num_sections_loaded = 0;
- for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
- SectionSP ondisk_section_sp(
- ondisk_section_list->GetSectionAtIndex(sect_idx));
- if (ondisk_section_sp) {
- // Don't ever load __LINKEDIT as it may or may not be actually
- // mapped into memory and there is no current way to tell.
- // I filed rdar://problem/12851706 to track being able to tell
- // if the __LINKEDIT is actually mapped, but until then, we need
- // to not load the __LINKEDIT
- if (ignore_linkedit &&
- ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
- continue;
-
- const Section *memory_section =
- memory_section_list
- ->FindSectionByName(ondisk_section_sp->GetName())
- .get();
- if (memory_section) {
- target.SetSectionLoadAddress(ondisk_section_sp,
- memory_section->GetFileAddress());
- ++num_sections_loaded;
- }
- }
- }
- if (num_sections_loaded > 0)
- m_load_process_stop_id = process->GetStopID();
- else
- m_module_sp.reset(); // No sections were loaded
- } else
- m_module_sp.reset(); // One or both section lists
- } else
- m_module_sp.reset(); // One or both object files missing
- } else
- m_module_sp.reset(); // UUID mismatch
- }
-
- bool is_loaded = IsLoaded();
-
- if (is_loaded && m_module_sp && IsKernel()) {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s) {
- ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
- if (kernel_object_file) {
- addr_t file_address =
- kernel_object_file->GetBaseAddress().GetFileAddress();
- if (m_load_address != LLDB_INVALID_ADDRESS &&
- file_address != LLDB_INVALID_ADDRESS) {
- s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
- m_load_address - file_address);
- }
- }
- {
- s->Printf("Loaded kernel file %s\n",
- m_module_sp->GetFileSpec().GetPath().c_str());
- }
- s->Flush();
- }
- }
- return is_loaded;
-}
-
-uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize() {
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
- if (m_module_sp)
- return m_module_sp->GetArchitecture().GetAddressByteSize();
- return 0;
-}
-
-lldb::ByteOrder DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder() {
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture().GetByteOrder();
- if (m_module_sp)
- return m_module_sp->GetArchitecture().GetByteOrder();
- return endian::InlHostByteOrder();
-}
-
-lldb_private::ArchSpec
-DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture();
- if (m_module_sp)
- return m_module_sp->GetArchitecture();
- return lldb_private::ArchSpec();
-}
-
-//----------------------------------------------------------------------
-// Load the kernel module and initialize the "m_kernel" member. Return true
-// _only_ if the kernel is loaded the first time through (subsequent calls to
-// this function should return false after the kernel has been already loaded).
-//----------------------------------------------------------------------
-void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
- if (!m_kext_summary_header_ptr_addr.IsValid()) {
- m_kernel.Clear();
- m_kernel.SetModule(m_process->GetTarget().GetExecutableModule());
- m_kernel.SetIsKernel(true);
-
- ConstString kernel_name("mach_kernel");
- if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
- !m_kernel.GetModule()
- ->GetObjectFile()
- ->GetFileSpec()
- .GetFilename()
- .IsEmpty()) {
- kernel_name =
- m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
- }
- m_kernel.SetName(kernel_name.AsCString());
-
- if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
- m_kernel.SetLoadAddress(m_kernel_load_address);
- if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
- m_kernel.GetModule()) {
- // We didn't get a hint from the process, so we will try the kernel at
- // the address that it exists at in the file if we have one
- ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
- if (kernel_object_file) {
- addr_t load_address =
- kernel_object_file->GetBaseAddress().GetLoadAddress(
- &m_process->GetTarget());
- addr_t file_address =
- kernel_object_file->GetBaseAddress().GetFileAddress();
- if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
- m_kernel.SetLoadAddress(load_address);
- if (load_address != file_address) {
- // Don't accidentally relocate the kernel to the File address --
- // the Load address has already been set to its actual in-memory
- // address. Mark it as IsLoaded.
- m_kernel.SetProcessStopId(m_process->GetStopID());
- }
- } else {
- m_kernel.SetLoadAddress(file_address);
- }
- }
- }
- }
-
- if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
- if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
- m_kernel.LoadImageAtFileAddress(m_process);
- }
- }
-
- // The operating system plugin gets loaded and initialized in
- // LoadImageUsingMemoryModule when we discover the kernel dSYM. For a core
- // file in particular, that's the wrong place to do this, since we haven't
- // fixed up the section addresses yet. So let's redo it here.
- LoadOperatingSystemPlugin(false);
-
- if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
- static ConstString kext_summary_symbol("gLoadedKextSummaries");
- const Symbol *symbol =
- m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
- kext_summary_symbol, eSymbolTypeData);
- if (symbol) {
- m_kext_summary_header_ptr_addr = symbol->GetAddress();
- // Update all image infos
- ReadAllKextSummaries();
- }
- } else {
- m_kernel.Clear();
- }
- }
-}
-
-//----------------------------------------------------------------------
-// Static callback function that gets called when our DYLD notification
-// breakpoint gets hit. We update all of our image infos and then let our super
-// class DynamicLoader class decide if we should stop or not (based on global
-// preference).
-//----------------------------------------------------------------------
-bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
- void *baton, StoppointCallbackContext *context, user_id_t break_id,
- user_id_t break_loc_id) {
- return static_cast<DynamicLoaderDarwinKernel *>(baton)->BreakpointHit(
- context, break_id, break_loc_id);
-}
-
-bool DynamicLoaderDarwinKernel::BreakpointHit(StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
-
- ReadAllKextSummaries();
-
- if (log)
- PutToLog(log);
-
- return GetStopWhenImagesChange();
-}
-
-bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // the all image infos is already valid for this process stop ID
-
- if (m_kext_summary_header_ptr_addr.IsValid()) {
- const uint32_t addr_size = m_kernel.GetAddressByteSize();
- const ByteOrder byte_order = m_kernel.GetByteOrder();
- Status error;
- // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure which
- // is currently 4 uint32_t and a pointer.
- uint8_t buf[24];
- DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
- const size_t count = 4 * sizeof(uint32_t) + addr_size;
- const bool prefer_file_cache = false;
- if (m_process->GetTarget().ReadPointerFromMemory(
- m_kext_summary_header_ptr_addr, prefer_file_cache, error,
- m_kext_summary_header_addr)) {
- // We got a valid address for our kext summary header and make sure it
- // isn't NULL
- if (m_kext_summary_header_addr.IsValid() &&
- m_kext_summary_header_addr.GetFileAddress() != 0) {
- const size_t bytes_read = m_process->GetTarget().ReadMemory(
- m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
- if (bytes_read == count) {
- lldb::offset_t offset = 0;
- m_kext_summary_header.version = data.GetU32(&offset);
- if (m_kext_summary_header.version > 128) {
- Stream *s =
- m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf("WARNING: Unable to read kext summary header, got "
- "improbable version number %u\n",
- m_kext_summary_header.version);
- // If we get an improbably large version number, we're probably
- // getting bad memory.
- m_kext_summary_header_addr.Clear();
- return false;
- }
- if (m_kext_summary_header.version >= 2) {
- m_kext_summary_header.entry_size = data.GetU32(&offset);
- if (m_kext_summary_header.entry_size > 4096) {
- // If we get an improbably large entry_size, we're probably
- // getting bad memory.
- Stream *s =
- m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf("WARNING: Unable to read kext summary header, got "
- "improbable entry_size %u\n",
- m_kext_summary_header.entry_size);
- m_kext_summary_header_addr.Clear();
- return false;
- }
- } else {
- // Versions less than 2 didn't have an entry size, it was hard
- // coded
- m_kext_summary_header.entry_size =
- KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
- }
- m_kext_summary_header.entry_count = data.GetU32(&offset);
- if (m_kext_summary_header.entry_count > 10000) {
- // If we get an improbably large number of kexts, we're probably
- // getting bad memory.
- Stream *s =
- m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf("WARNING: Unable to read kext summary header, got "
- "improbable number of kexts %u\n",
- m_kext_summary_header.entry_count);
- m_kext_summary_header_addr.Clear();
- return false;
- }
- return true;
- }
- }
- }
- }
- m_kext_summary_header_addr.Clear();
- return false;
-}
-
-// We've either (a) just attached to a new kernel, or (b) the kexts-changed
-// breakpoint was hit and we need to figure out what kexts have been added or
-// removed. Read the kext summaries from the inferior kernel memory, compare
-// them against the m_known_kexts vector and update the m_known_kexts vector as
-// needed to keep in sync with the inferior.
-
-bool DynamicLoaderDarwinKernel::ParseKextSummaries(
- const Address &kext_summary_addr, uint32_t count) {
- KextImageInfo::collection kext_summaries;
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("Kexts-changed breakpoint hit, there are %d kexts currently.\n",
- count);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (!ReadKextSummaries(kext_summary_addr, count, kext_summaries))
- return false;
-
- // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the
- // user requested no kext loading, don't print any messages about kexts &
- // don't try to read them.
- const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
-
- // By default, all kexts we've loaded in the past are marked as "remove" and
- // all of the kexts we just found out about from ReadKextSummaries are marked
- // as "add".
- std::vector<bool> to_be_removed(m_known_kexts.size(), true);
- std::vector<bool> to_be_added(count, true);
-
- int number_of_new_kexts_being_added = 0;
- int number_of_old_kexts_being_removed = m_known_kexts.size();
-
- const uint32_t new_kexts_size = kext_summaries.size();
- const uint32_t old_kexts_size = m_known_kexts.size();
-
- // The m_known_kexts vector may have entries that have been Cleared, or are a
- // kernel.
- for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
- bool ignore = false;
- KextImageInfo &image_info = m_known_kexts[old_kext];
- if (image_info.IsKernel()) {
- ignore = true;
- } else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
- !image_info.GetModule()) {
- ignore = true;
- }
-
- if (ignore) {
- number_of_old_kexts_being_removed--;
- to_be_removed[old_kext] = false;
- }
- }
-
- // Scan over the list of kexts we just read from the kernel, note those that
- // need to be added and those already loaded.
- for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++) {
- bool add_this_one = true;
- for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
- if (m_known_kexts[old_kext] == kext_summaries[new_kext]) {
- // We already have this kext, don't re-load it.
- to_be_added[new_kext] = false;
- // This kext is still present, do not remove it.
- to_be_removed[old_kext] = false;
-
- number_of_old_kexts_being_removed--;
- add_this_one = false;
- break;
- }
- }
- // If this "kext" entry is actually an alias for the kernel -- the kext was
- // compiled into the kernel or something -- then we don't want to load the
- // kernel's text section at a different address. Ignore this kext entry.
- if (kext_summaries[new_kext].GetUUID().IsValid()
- && m_kernel.GetUUID().IsValid()
- && kext_summaries[new_kext].GetUUID() == m_kernel.GetUUID()) {
- to_be_added[new_kext] = false;
- break;
- }
- if (add_this_one) {
- number_of_new_kexts_being_added++;
- }
- }
-
- if (number_of_new_kexts_being_added == 0 &&
- number_of_old_kexts_being_removed == 0)
- return true;
-
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- if (s && load_kexts) {
- if (number_of_new_kexts_being_added > 0 &&
- number_of_old_kexts_being_removed > 0) {
- s->Printf("Loading %d kext modules and unloading %d kext modules ",
- number_of_new_kexts_being_added,
- number_of_old_kexts_being_removed);
- } else if (number_of_new_kexts_being_added > 0) {
- s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added);
- } else if (number_of_old_kexts_being_removed > 0) {
- s->Printf("Unloading %d kext modules ",
- number_of_old_kexts_being_removed);
- }
- }
-
- if (log) {
- if (load_kexts) {
- log->Printf("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts "
- "added, %d kexts removed",
- number_of_new_kexts_being_added,
- number_of_old_kexts_being_removed);
- } else {
- log->Printf(
- "DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is "
- "disabled, else would have %d kexts added, %d kexts removed",
- number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
- }
- }
-
- if (number_of_new_kexts_being_added > 0) {
- ModuleList loaded_module_list;
-
- const uint32_t num_of_new_kexts = kext_summaries.size();
- for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++) {
- if (to_be_added[new_kext]) {
- KextImageInfo &image_info = kext_summaries[new_kext];
- if (load_kexts) {
- if (!image_info.LoadImageUsingMemoryModule(m_process)) {
- image_info.LoadImageAtFileAddress(m_process);
- }
- }
-
- m_known_kexts.push_back(image_info);
-
- if (image_info.GetModule() &&
- m_process->GetStopID() == image_info.GetProcessStopId())
- loaded_module_list.AppendIfNeeded(image_info.GetModule());
-
- if (s && load_kexts)
- s->Printf(".");
-
- if (log)
- kext_summaries[new_kext].PutToLog(log);
- }
- }
- m_process->GetTarget().ModulesDidLoad(loaded_module_list);
- }
-
- if (number_of_old_kexts_being_removed > 0) {
- ModuleList loaded_module_list;
- const uint32_t num_of_old_kexts = m_known_kexts.size();
- for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++) {
- ModuleList unloaded_module_list;
- if (to_be_removed[old_kext]) {
- KextImageInfo &image_info = m_known_kexts[old_kext];
- // You can't unload the kernel.
- if (!image_info.IsKernel()) {
- if (image_info.GetModule()) {
- unloaded_module_list.AppendIfNeeded(image_info.GetModule());
- }
- if (s)
- s->Printf(".");
- image_info.Clear();
- // should pull it out of the KextImageInfos vector but that would
- // mutate the list and invalidate the to_be_removed bool vector;
- // leaving it in place once Cleared() is relatively harmless.
- }
- }
- m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
- }
- }
-
- if (s && load_kexts) {
- s->Printf(" done.\n");
- s->Flush();
- }
-
- return true;
-}
-
-uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
- const Address &kext_summary_addr, uint32_t image_infos_count,
- KextImageInfo::collection &image_infos) {
- const ByteOrder endian = m_kernel.GetByteOrder();
- const uint32_t addr_size = m_kernel.GetAddressByteSize();
-
- image_infos.resize(image_infos_count);
- const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
- DataBufferHeap data(count, 0);
- Status error;
-
- const bool prefer_file_cache = false;
- const size_t bytes_read = m_process->GetTarget().ReadMemory(
- kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
- error);
- if (bytes_read == count) {
-
- DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
- addr_size);
- uint32_t i = 0;
- for (uint32_t kext_summary_offset = 0;
- i < image_infos.size() &&
- extractor.ValidOffsetForDataOfSize(kext_summary_offset,
- m_kext_summary_header.entry_size);
- ++i, kext_summary_offset += m_kext_summary_header.entry_size) {
- lldb::offset_t offset = kext_summary_offset;
- const void *name_data =
- extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
- if (name_data == NULL)
- break;
- image_infos[i].SetName((const char *)name_data);
- UUID uuid = UUID::fromOptionalData(extractor.GetData(&offset, 16), 16);
- image_infos[i].SetUUID(uuid);
- image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
- image_infos[i].SetSize(extractor.GetU64(&offset));
- }
- if (i < image_infos.size())
- image_infos.resize(i);
- } else {
- image_infos.clear();
- }
- return image_infos.size();
-}
-
-bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (ReadKextSummaryHeader()) {
- if (m_kext_summary_header.entry_count > 0 &&
- m_kext_summary_header_addr.IsValid()) {
- Address summary_addr(m_kext_summary_header_addr);
- summary_addr.Slide(m_kext_summary_header.GetSize());
- if (!ParseKextSummaries(summary_addr,
- m_kext_summary_header.entry_count)) {
- m_known_kexts.clear();
- }
- return true;
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// Dump an image info structure to the file handle provided.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
- if (m_load_address == LLDB_INVALID_ADDRESS) {
- LLDB_LOG(log, "uuid={0} name=\"{1}\" (UNLOADED)", m_uuid.GetAsString(),
- m_name);
- } else {
- LLDB_LOG(log, "addr={0:x+16} size={1:x+16} uuid={2} name=\"{3}\"",
- m_load_address, m_size, m_uuid.GetAsString(), m_name);
- }
-}
-
-//----------------------------------------------------------------------
-// Dump the _dyld_all_image_infos members and all current image infos that we
-// have parsed to the file handle provided.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
- if (log == NULL)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64
- " { version=%u, entry_size=%u, entry_count=%u }",
- m_kext_summary_header_addr.GetFileAddress(),
- m_kext_summary_header.version, m_kext_summary_header.entry_size,
- m_kext_summary_header.entry_count);
-
- size_t i;
- const size_t count = m_known_kexts.size();
- if (count > 0) {
- log->PutCString("Loaded:");
- for (i = 0; i < count; i++)
- m_known_kexts[i].PutToLog(log);
- }
-}
-
-void DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) {
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
- __FUNCTION__, StateAsCString(m_process->GetState()));
- Clear(true);
- m_process = process;
-}
-
-void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded() {
- if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule()) {
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
- __FUNCTION__, StateAsCString(m_process->GetState()));
-
- const bool internal_bp = true;
- const bool hardware = false;
- const LazyBool skip_prologue = eLazyBoolNo;
- FileSpecList module_spec_list;
- module_spec_list.Append(m_kernel.GetModule()->GetFileSpec());
- Breakpoint *bp =
- m_process->GetTarget()
- .CreateBreakpoint(&module_spec_list, NULL,
- "OSKextLoadedKextSummariesUpdated",
- eFunctionNameTypeFull, eLanguageTypeUnknown, 0,
- skip_prologue, internal_bp, hardware)
- .get();
-
- bp->SetCallback(DynamicLoaderDarwinKernel::BreakpointHitCallback, this,
- true);
- m_break_id = bp->GetID();
- }
-}
-
-//----------------------------------------------------------------------
-// Member function that gets called when the process state changes.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwinKernel::PrivateProcessStateChanged(Process *process,
- StateType state) {
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__,
- StateAsCString(state));
- switch (state) {
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear(false);
- break;
-
- case eStateStopped:
- UpdateIfNeeded();
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
- }
-}
-
-ThreadPlanSP
-DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan(Thread &thread,
- bool stop_others) {
- ThreadPlanSP thread_plan_sp;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Could not find symbol for step through.");
- return thread_plan_sp;
-}
-
-Status DynamicLoaderDarwinKernel::CanLoadImage() {
- Status error;
- error.SetErrorString(
- "always unsafe to load or unload shared libraries in the darwin kernel");
- return error;
-}
-
-void DynamicLoaderDarwinKernel::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance,
- DebuggerInitialize);
-}
-
-void DynamicLoaderDarwinKernel::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-void DynamicLoaderDarwinKernel::DebuggerInitialize(
- lldb_private::Debugger &debugger) {
- if (!PluginManager::GetSettingForDynamicLoaderPlugin(
- debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForDynamicLoaderPlugin(
- debugger, GetGlobalProperties()->GetValueProperties(),
- ConstString("Properties for the DynamicLoaderDarwinKernel plug-in."),
- is_global_setting);
- }
-}
-
-lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginNameStatic() {
- static ConstString g_name("darwin-kernel");
- return g_name;
-}
-
-const char *DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() {
- return "Dynamic loader plug-in that watches for shared library loads/unloads "
- "in the MacOSX kernel.";
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t DynamicLoaderDarwinKernel::GetPluginVersion() { return 1; }
-
-lldb::ByteOrder
-DynamicLoaderDarwinKernel::GetByteOrderFromMagic(uint32_t magic) {
- switch (magic) {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- return endian::InlHostByteOrder();
-
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- return lldb::eByteOrderLittle;
- else
- return lldb::eByteOrderBig;
-
- default:
- break;
- }
- return lldb::eByteOrderInvalid;
-}
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
deleted file mode 100644
index 7aacebd9b50fb..0000000000000
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ /dev/null
@@ -1,307 +0,0 @@
-//===-- DynamicLoaderDarwinKernel.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_DynamicLoaderDarwinKernel_h_
-#define liblldb_DynamicLoaderDarwinKernel_h_
-
-#include <mutex>
-#include <string>
-#include <vector>
-
-
-#include "lldb/Host/SafeMachO.h"
-
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/UUID.h"
-
-class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
-public:
- DynamicLoaderDarwinKernel(lldb_private::Process *process,
- lldb::addr_t kernel_addr);
-
- ~DynamicLoaderDarwinKernel() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::DynamicLoader *
- CreateInstance(lldb_private::Process *process, bool force);
-
- static void DebuggerInitialize(lldb_private::Debugger &debugger);
-
- static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
-
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void DidAttach() override;
-
- void DidLaunch() override;
-
- lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
-
- lldb_private::Status CanLoadImage() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
-protected:
- void PrivateInitialize(lldb_private::Process *process);
-
- void PrivateProcessStateChanged(lldb_private::Process *process,
- lldb::StateType state);
-
- void UpdateIfNeeded();
-
- void LoadKernelModuleIfNeeded();
-
- void Clear(bool clear_process);
-
- void PutToLog(lldb_private::Log *log) const;
-
- static bool
- BreakpointHitCallback(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
- bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
- uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
-
- static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
-
- enum {
- KERNEL_MODULE_MAX_NAME = 64u,
- // Versions less than 2 didn't have an entry size,
- // they had a 64 bit name, 16 byte UUID, 8 byte addr,
- // 8 byte size, 8 byte version, 4 byte load tag, and
- // 4 byte flags
- KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
- };
-
- // class KextImageInfo represents a single kext or kernel binary image.
- // The class was designed to hold the information from the
- // OSKextLoadedKextSummary
- // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel
- // maintains
- // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
- // structure,
- // which points to an array of OSKextLoadedKextSummary's).
- //
- // A KextImageInfos may have -
- //
- // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
- // (read straight out of the kernel's list-of-kexts loaded)
- // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
- // (very unlikely to have any symbolic information)
- // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
- // info
- // or a dSYM
- //
- // For performance reasons, the developer may prefer that lldb not load the
- // kexts out
- // of memory at the start of a kernel session. But we should build up /
- // maintain a
- // list of kexts that the kernel has told us about so we can relocate a kext
- // module
- // later if the user explicitly adds it to the target.
-
- class KextImageInfo {
- public:
- KextImageInfo()
- : m_name(), m_module_sp(), m_memory_module_sp(),
- m_load_process_stop_id(UINT32_MAX), m_uuid(),
- m_load_address(LLDB_INVALID_ADDRESS), m_size(0),
- m_kernel_image(false) {}
-
- void Clear() {
- m_load_address = LLDB_INVALID_ADDRESS;
- m_size = 0;
- m_name.clear();
- m_uuid.Clear();
- m_module_sp.reset();
- m_memory_module_sp.reset();
- m_load_process_stop_id = UINT32_MAX;
- }
-
- bool LoadImageAtFileAddress(lldb_private::Process *process);
-
- bool LoadImageUsingMemoryModule(lldb_private::Process *process);
-
- bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
-
- void SetLoadAddress(
- lldb::addr_t load_addr); // Address of the Mach-O header for this binary
-
- lldb::addr_t
- GetLoadAddress() const; // Address of the Mach-O header for this binary
-
- lldb_private::UUID GetUUID() const;
-
- void SetUUID(const lldb_private::UUID &uuid);
-
- void SetName(const char *);
-
- std::string GetName() const;
-
- void SetModule(lldb::ModuleSP module);
-
- lldb::ModuleSP GetModule();
-
- // try to fill in m_memory_module_sp from memory based on the m_load_address
- bool ReadMemoryModule(lldb_private::Process *process);
-
- bool IsKernel()
- const; // true if this is the mach_kernel; false if this is a kext
-
- void SetIsKernel(bool is_kernel);
-
- uint64_t GetSize() const;
-
- void SetSize(uint64_t size);
-
- uint32_t
- GetProcessStopId() const; // the stop-id when this binary was first noticed
-
- void SetProcessStopId(uint32_t stop_id);
-
- bool operator==(const KextImageInfo &rhs);
-
- uint32_t GetAddressByteSize(); // as determined by Mach-O header
-
- lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
-
- lldb_private::ArchSpec
- GetArchitecture() const; // as determined by Mach-O header
-
- void PutToLog(lldb_private::Log *log) const;
-
- typedef std::vector<KextImageInfo> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- private:
- std::string m_name;
- lldb::ModuleSP m_module_sp;
- lldb::ModuleSP m_memory_module_sp;
- uint32_t m_load_process_stop_id; // the stop-id when this module was added
- // to the Target
- lldb_private::UUID
- m_uuid; // UUID for this dylib if it has one, else all zeros
- lldb::addr_t m_load_address;
- uint64_t m_size;
- bool m_kernel_image; // true if this is the kernel, false if this is a kext
- };
-
- struct OSKextLoadedKextSummaryHeader {
- uint32_t version;
- uint32_t entry_size;
- uint32_t entry_count;
- lldb::addr_t image_infos_addr;
-
- OSKextLoadedKextSummaryHeader()
- : version(0), entry_size(0), entry_count(0),
- image_infos_addr(LLDB_INVALID_ADDRESS) {}
-
- uint32_t GetSize() {
- switch (version) {
- case 0:
- return 0; // Can't know the size without a valid version
- case 1:
- return 8; // Version 1 only had a version + entry_count
- default:
- break;
- }
- // Version 2 and above has version, entry_size, entry_count, and reserved
- return 16;
- }
-
- void Clear() {
- version = 0;
- entry_size = 0;
- entry_count = 0;
- image_infos_addr = LLDB_INVALID_ADDRESS;
- }
-
- bool IsValid() const { return version >= 1 || version <= 2; }
- };
-
- void RegisterNotificationCallbacks();
-
- void UnregisterNotificationCallbacks();
-
- void SetNotificationBreakpointIfNeeded();
-
- bool ReadAllKextSummaries();
-
- bool ReadKextSummaryHeader();
-
- bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
- uint32_t count);
-
- void
- UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
-
- uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
- uint32_t image_infos_count,
- KextImageInfo::collection &image_infos);
-
- static lldb::addr_t
- SearchForKernelAtSameLoadAddr(lldb_private::Process *process);
-
- static lldb::addr_t
- SearchForKernelWithDebugHints(lldb_private::Process *process);
-
- static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);
-
- static lldb::addr_t
- SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
-
- static bool
- ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh);
-
- static lldb_private::UUID
- CheckForKernelImageAtAddress(lldb::addr_t addr,
- lldb_private::Process *process);
-
- lldb::addr_t m_kernel_load_address;
- KextImageInfo m_kernel; // Info about the current kernel image being used
-
- lldb_private::Address m_kext_summary_header_ptr_addr;
- lldb_private::Address m_kext_summary_header_addr;
- OSKextLoadedKextSummaryHeader m_kext_summary_header;
- KextImageInfo::collection m_known_kexts;
- mutable std::recursive_mutex m_mutex;
- lldb::user_id_t m_break_id;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel);
-};
-
-#endif // liblldb_DynamicLoaderDarwinKernel_h_
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/CMakeLists.txt b/source/Plugins/DynamicLoader/Hexagon-DYLD/CMakeLists.txt
deleted file mode 100644
index c590457d0a54d..0000000000000
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginDynamicLoaderHexagonDYLD PLUGIN
- HexagonDYLDRendezvous.cpp
- DynamicLoaderHexagonDYLD.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbSymbol
- lldbTarget
- )
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt b/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
deleted file mode 100644
index 515c82dcaca97..0000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
- DynamicLoaderMacOSXDYLD.cpp
- DynamicLoaderMacOS.cpp
- DynamicLoaderDarwin.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbExpression
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
deleted file mode 100644
index 944be9633e00e..0000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ /dev/null
@@ -1,1143 +0,0 @@
-//===-- DynamicLoaderDarwin.cpp -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DynamicLoaderDarwin.h"
-
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Expression/DiagnosticManager.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/ABI.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadPlanCallFunction.h"
-#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-
-//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
-#ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
-
-#ifndef __APPLE__
-#include "Utility/UuidCompatibility.h"
-#else
-#include <uuid/uuid.h>
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-DynamicLoaderDarwin::DynamicLoaderDarwin(Process *process)
- : DynamicLoader(process), m_dyld_module_wp(), m_libpthread_module_wp(),
- m_pthread_getspecific_addr(), m_tid_to_tls_map(), m_dyld_image_infos(),
- m_dyld_image_infos_stop_id(UINT32_MAX), m_dyld(), m_mutex() {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-DynamicLoaderDarwin::~DynamicLoaderDarwin() {}
-
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void DynamicLoaderDarwin::DidAttach() {
- PrivateInitialize(m_process);
- DoInitialImageFetch();
- SetNotificationBreakpoint();
-}
-
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void DynamicLoaderDarwin::DidLaunch() {
- PrivateInitialize(m_process);
- DoInitialImageFetch();
- SetNotificationBreakpoint();
-}
-
-//----------------------------------------------------------------------
-// Clear out the state of this class.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwin::Clear(bool clear_process) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (clear_process)
- m_process = NULL;
- m_dyld_image_infos.clear();
- m_dyld_image_infos_stop_id = UINT32_MAX;
- m_dyld.Clear(false);
-}
-
-ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
- ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
- if (did_create_ptr)
- *did_create_ptr = false;
-
- Target &target = m_process->GetTarget();
- const ModuleList &target_images = target.GetImages();
- ModuleSpec module_spec(image_info.file_spec);
- module_spec.GetUUID() = image_info.uuid;
- ModuleSP module_sp(target_images.FindFirstModule(module_spec));
-
- if (module_sp && !module_spec.GetUUID().IsValid() &&
- !module_sp->GetUUID().IsValid()) {
- // No UUID, we must rely upon the cached module modification time and the
- // modification time of the file on disk
- if (module_sp->GetModificationTime() !=
- FileSystem::Instance().GetModificationTime(module_sp->GetFileSpec()))
- module_sp.reset();
- }
-
- if (!module_sp) {
- if (can_create) {
- module_sp = target.GetSharedModule(module_spec);
- if (!module_sp || module_sp->GetObjectFile() == NULL)
- module_sp = m_process->ReadModuleFromMemory(image_info.file_spec,
- image_info.address);
-
- if (did_create_ptr)
- *did_create_ptr = (bool)module_sp;
- }
- }
- return module_sp;
-}
-
-void DynamicLoaderDarwin::UnloadImages(
- const std::vector<lldb::addr_t> &solib_addresses) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return;
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- Target &target = m_process->GetTarget();
- if (log)
- log->Printf("Removing %" PRId64 " modules.",
- (uint64_t)solib_addresses.size());
-
- ModuleList unloaded_module_list;
-
- for (addr_t solib_addr : solib_addresses) {
- Address header;
- if (header.SetLoadAddress(solib_addr, &target)) {
- if (header.GetOffset() == 0) {
- ModuleSP module_to_remove(header.GetModule());
- if (module_to_remove.get()) {
- if (log)
- log->Printf("Removing module at address 0x%" PRIx64, solib_addr);
- // remove the sections from the Target
- UnloadSections(module_to_remove);
- // add this to the list of modules to remove
- unloaded_module_list.AppendIfNeeded(module_to_remove);
- // remove the entry from the m_dyld_image_infos
- ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
- for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
- if (solib_addr == (*pos).address) {
- m_dyld_image_infos.erase(pos);
- break;
- }
- }
- }
- }
- }
- }
-
- if (unloaded_module_list.GetSize() > 0) {
- if (log) {
- log->PutCString("Unloaded:");
- unloaded_module_list.LogUUIDAndPaths(
- log, "DynamicLoaderDarwin::UnloadModules");
- }
- m_process->GetTarget().GetImages().Remove(unloaded_module_list);
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- }
-}
-
-void DynamicLoaderDarwin::UnloadAllImages() {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- ModuleList unloaded_modules_list;
-
- Target &target = m_process->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
-
- size_t num_modules = target_modules.GetSize();
- ModuleSP dyld_sp(GetDYLDModule());
-
- for (size_t i = 0; i < num_modules; i++) {
- ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
-
- // Don't remove dyld - else we'll lose our breakpoint notifying us about
- // libraries being re-loaded...
- if (module_sp.get() != nullptr && module_sp.get() != dyld_sp.get()) {
- UnloadSections(module_sp);
- unloaded_modules_list.Append(module_sp);
- }
- }
-
- if (unloaded_modules_list.GetSize() != 0) {
- if (log) {
- log->PutCString("Unloaded:");
- unloaded_modules_list.LogUUIDAndPaths(
- log, "DynamicLoaderDarwin::UnloadAllImages");
- }
- target.GetImages().Remove(unloaded_modules_list);
- m_dyld_image_infos.clear();
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- }
-}
-
-//----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the updated INFO
-// that is passed in.
-//----------------------------------------------------------------------
-bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
- ImageInfo &info) {
- bool changed = false;
- if (module) {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file) {
- SectionList *section_list = image_object_file->GetSectionList();
- if (section_list) {
- std::vector<uint32_t> inaccessible_segment_indexes;
- // We now know the slide amount, so go through all sections and update
- // the load addresses with the correct values.
- const size_t num_segments = info.segments.size();
- for (size_t i = 0; i < num_segments; ++i) {
- // Only load a segment if it has protections. Things like __PAGEZERO
- // don't have any protections, and they shouldn't be slid
- SectionSP section_sp(
- section_list->FindSectionByName(info.segments[i].name));
-
- if (info.segments[i].maxprot == 0) {
- inaccessible_segment_indexes.push_back(i);
- } else {
- const addr_t new_section_load_addr =
- info.segments[i].vmaddr + info.slide;
- static ConstString g_section_name_LINKEDIT("__LINKEDIT");
-
- if (section_sp) {
- // __LINKEDIT sections from files in the shared cache can overlap
- // so check to see what the segment name is and pass "false" so
- // we don't warn of overlapping "Section" objects, and "true" for
- // all other sections.
- const bool warn_multiple =
- section_sp->GetName() != g_section_name_LINKEDIT;
-
- changed = m_process->GetTarget().SetSectionLoadAddress(
- section_sp, new_section_load_addr, warn_multiple);
- } else {
- Host::SystemLog(
- Host::eSystemLogWarning,
- "warning: unable to find and load segment named '%s' at "
- "0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- (uint64_t)new_section_load_addr,
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
-
- // If the loaded the file (it changed) and we have segments that are
- // not readable or writeable, add them to the invalid memory region
- // cache for the process. This will typically only be the __PAGEZERO
- // segment in the main executable. We might be able to apply this more
- // generally to more sections that have no protections in the future,
- // but for now we are going to just do __PAGEZERO.
- if (changed && !inaccessible_segment_indexes.empty()) {
- for (uint32_t i = 0; i < inaccessible_segment_indexes.size(); ++i) {
- const uint32_t seg_idx = inaccessible_segment_indexes[i];
- SectionSP section_sp(
- section_list->FindSectionByName(info.segments[seg_idx].name));
-
- if (section_sp) {
- static ConstString g_pagezero_section_name("__PAGEZERO");
- if (g_pagezero_section_name == section_sp->GetName()) {
- // __PAGEZERO never slides...
- const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
- const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
- Process::LoadRange pagezero_range(vmaddr, vmsize);
- m_process->AddInvalidMemoryRegion(pagezero_range);
- }
- }
- }
- }
- }
- }
- }
- // We might have an in memory image that was loaded as soon as it was created
- if (info.load_stop_id == m_process->GetStopID())
- changed = true;
- else if (changed) {
- // Update the stop ID when this library was updated
- info.load_stop_id = m_process->GetStopID();
- }
- return changed;
-}
-
-//----------------------------------------------------------------------
-// Unload the segments in MODULE using the INFO that is passed in.
-//----------------------------------------------------------------------
-bool DynamicLoaderDarwin::UnloadModuleSections(Module *module,
- ImageInfo &info) {
- bool changed = false;
- if (module) {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file) {
- SectionList *section_list = image_object_file->GetSectionList();
- if (section_list) {
- const size_t num_segments = info.segments.size();
- for (size_t i = 0; i < num_segments; ++i) {
- SectionSP section_sp(
- section_list->FindSectionByName(info.segments[i].name));
- if (section_sp) {
- const addr_t old_section_load_addr =
- info.segments[i].vmaddr + info.slide;
- if (m_process->GetTarget().SetSectionUnloaded(
- section_sp, old_section_load_addr))
- changed = true;
- } else {
- Host::SystemLog(Host::eSystemLogWarning,
- "warning: unable to find and unload segment named "
- "'%s' in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
- }
- }
- return changed;
-}
-
-// Given a JSON dictionary (from debugserver, most likely) of binary images
-// loaded in the inferior process, add the images to the ImageInfo collection.
-
-bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
- StructuredData::ObjectSP image_details,
- ImageInfo::collection &image_infos) {
- StructuredData::ObjectSP images_sp =
- image_details->GetAsDictionary()->GetValueForKey("images");
- if (images_sp.get() == nullptr)
- return false;
-
- image_infos.resize(images_sp->GetAsArray()->GetSize());
-
- for (size_t i = 0; i < image_infos.size(); i++) {
- StructuredData::ObjectSP image_sp =
- images_sp->GetAsArray()->GetItemAtIndex(i);
- if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
- return false;
- StructuredData::Dictionary *image = image_sp->GetAsDictionary();
- // clang-format off
- if (!image->HasKey("load_address") ||
- !image->HasKey("pathname") ||
- !image->HasKey("mod_date") ||
- !image->HasKey("mach_header") ||
- image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr ||
- !image->HasKey("segments") ||
- image->GetValueForKey("segments")->GetAsArray() == nullptr ||
- !image->HasKey("uuid")) {
- return false;
- }
- // clang-format on
- image_infos[i].address =
- image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
- image_infos[i].mod_date =
- image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
- image_infos[i].file_spec.SetFile(
- image->GetValueForKey("pathname")->GetAsString()->GetValue(),
- FileSpec::Style::native);
-
- StructuredData::Dictionary *mh =
- image->GetValueForKey("mach_header")->GetAsDictionary();
- image_infos[i].header.magic =
- mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
- image_infos[i].header.cputype =
- mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
- image_infos[i].header.cpusubtype =
- mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
- image_infos[i].header.filetype =
- mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
-
- if (image->HasKey("min_version_os_name")) {
- std::string os_name = image->GetValueForKey("min_version_os_name")
- ->GetAsString()
- ->GetValue();
- if (os_name == "macosx")
- image_infos[i].os_type = llvm::Triple::MacOSX;
- else if (os_name == "ios" || os_name == "iphoneos")
- image_infos[i].os_type = llvm::Triple::IOS;
- else if (os_name == "tvos")
- image_infos[i].os_type = llvm::Triple::TvOS;
- else if (os_name == "watchos")
- image_infos[i].os_type = llvm::Triple::WatchOS;
- // NEED_BRIDGEOS_TRIPLE else if (os_name == "bridgeos")
- // NEED_BRIDGEOS_TRIPLE image_infos[i].os_type = llvm::Triple::BridgeOS;
- }
- if (image->HasKey("min_version_os_sdk")) {
- image_infos[i].min_version_os_sdk =
- image->GetValueForKey("min_version_os_sdk")
- ->GetAsString()
- ->GetValue();
- }
-
- // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
- // currently send them in the reply.
-
- if (mh->HasKey("flags"))
- image_infos[i].header.flags =
- mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.flags = 0;
-
- if (mh->HasKey("ncmds"))
- image_infos[i].header.ncmds =
- mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.ncmds = 0;
-
- if (mh->HasKey("sizeofcmds"))
- image_infos[i].header.sizeofcmds =
- mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.sizeofcmds = 0;
-
- StructuredData::Array *segments =
- image->GetValueForKey("segments")->GetAsArray();
- uint32_t segcount = segments->GetSize();
- for (size_t j = 0; j < segcount; j++) {
- Segment segment;
- StructuredData::Dictionary *seg =
- segments->GetItemAtIndex(j)->GetAsDictionary();
- segment.name =
- ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue());
- segment.vmaddr =
- seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
- segment.vmsize =
- seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
- segment.fileoff =
- seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
- segment.filesize =
- seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
- segment.maxprot =
- seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
-
- // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
- // currently send them in the reply.
-
- if (seg->HasKey("initprot"))
- segment.initprot =
- seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
- else
- segment.initprot = 0;
-
- if (seg->HasKey("flags"))
- segment.flags =
- seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- segment.flags = 0;
-
- if (seg->HasKey("nsects"))
- segment.nsects =
- seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
- else
- segment.nsects = 0;
-
- image_infos[i].segments.push_back(segment);
- }
-
- image_infos[i].uuid.SetFromStringRef(
- image->GetValueForKey("uuid")->GetAsString()->GetValue());
-
- // All sections listed in the dyld image info structure will all either be
- // fixed up already, or they will all be off by a single slide amount that
- // is determined by finding the first segment that is at file offset zero
- // which also has bytes (a file size that is greater than zero) in the
- // object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = image_infos[i].segments.size();
- for (size_t k = 0; k < num_sections; ++k) {
- // Iterate through the object file sections to find the first section
- // that starts of file offset zero and that has bytes in the file...
- if ((image_infos[i].segments[k].fileoff == 0 &&
- image_infos[i].segments[k].filesize > 0) ||
- (image_infos[i].segments[k].name == ConstString("__TEXT"))) {
- image_infos[i].slide =
- image_infos[i].address - image_infos[i].segments[k].vmaddr;
- // We have found the slide amount, so we can exit this for loop.
- break;
- }
- }
- }
-
- return true;
-}
-
-void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
- ImageInfo::collection &image_infos) {
- uint32_t exe_idx = UINT32_MAX;
- uint32_t dyld_idx = UINT32_MAX;
- Target &target = m_process->GetTarget();
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- ConstString g_dyld_sim_filename("dyld_sim");
-
- ArchSpec target_arch = target.GetArchitecture();
- const size_t image_infos_size = image_infos.size();
- for (size_t i = 0; i < image_infos_size; i++) {
- if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER) {
- // In a "simulator" process (an x86 process that is
- // ios/tvos/watchos/bridgeos) we will have two dyld modules --
- // a "dyld" that we want to keep track of, and a "dyld_sim" which
- // we don't need to keep track of here. If the target is an x86
- // system and the OS of the dyld binary is ios/tvos/watchos/bridgeos,
- // then we are looking at dyld_sym.
-
- // debugserver has only recently (late 2016) started sending up the os
- // type for each binary it sees -- so if we don't have an os type, use a
- // filename check as our next best guess.
- if (image_infos[i].os_type == llvm::Triple::OSType::UnknownOS) {
- if (image_infos[i].file_spec.GetFilename() != g_dyld_sim_filename) {
- dyld_idx = i;
- }
- } else if (target_arch.GetTriple().getArch() == llvm::Triple::x86 ||
- target_arch.GetTriple().getArch() == llvm::Triple::x86_64) {
- if (image_infos[i].os_type != llvm::Triple::OSType::IOS &&
- image_infos[i].os_type != llvm::Triple::TvOS &&
- image_infos[i].os_type != llvm::Triple::WatchOS) {
- // NEED_BRIDGEOS_TRIPLE image_infos[i].os_type != llvm::Triple::BridgeOS) {
- dyld_idx = i;
- }
- }
- else {
- // catch-all for any other environment -- trust that dyld is actually
- // dyld
- dyld_idx = i;
- }
- } else if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) {
- exe_idx = i;
- }
- }
-
- if (exe_idx != UINT32_MAX) {
- const bool can_create = true;
- ModuleSP exe_module_sp(
- FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL));
- if (exe_module_sp) {
- if (log)
- log->Printf("Found executable module: %s",
- exe_module_sp->GetFileSpec().GetPath().c_str());
- target.GetImages().AppendIfNeeded(exe_module_sp);
- UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);
- if (exe_module_sp.get() != target.GetExecutableModulePointer()) {
- target.SetExecutableModule(exe_module_sp, eLoadDependentsNo);
- }
- }
- }
-
- if (dyld_idx != UINT32_MAX) {
- const bool can_create = true;
- ModuleSP dyld_sp =
- FindTargetModuleForImageInfo(image_infos[dyld_idx], can_create, NULL);
- if (dyld_sp.get()) {
- if (log)
- log->Printf("Found dyld module: %s",
- dyld_sp->GetFileSpec().GetPath().c_str());
- target.GetImages().AppendIfNeeded(dyld_sp);
- UpdateImageLoadAddress(dyld_sp.get(), image_infos[dyld_idx]);
- SetDYLDModule(dyld_sp);
- }
- }
-}
-
-void DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo(
- ImageInfo &image_info) {
- if (image_info.header.filetype == llvm::MachO::MH_DYLINKER) {
- const bool can_create = true;
- ModuleSP dyld_sp =
- FindTargetModuleForImageInfo(image_info, can_create, NULL);
- if (dyld_sp.get()) {
- Target &target = m_process->GetTarget();
- target.GetImages().AppendIfNeeded(dyld_sp);
- UpdateImageLoadAddress(dyld_sp.get(), image_info);
- SetDYLDModule(dyld_sp);
- }
- }
-}
-
-void DynamicLoaderDarwin::SetDYLDModule(lldb::ModuleSP &dyld_module_sp) {
- m_dyld_module_wp = dyld_module_sp;
-}
-
-ModuleSP DynamicLoaderDarwin::GetDYLDModule() {
- ModuleSP dyld_sp(m_dyld_module_wp.lock());
- return dyld_sp;
-}
-
-bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
- ImageInfo::collection &image_infos) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // Now add these images to the main list.
- ModuleList loaded_module_list;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- Target &target = m_process->GetTarget();
- ModuleList &target_images = target.GetImages();
-
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
- if (log) {
- log->Printf("Adding new image at address=0x%16.16" PRIx64 ".",
- image_infos[idx].address);
- image_infos[idx].PutToLog(log);
- }
-
- m_dyld_image_infos.push_back(image_infos[idx]);
-
- ModuleSP image_module_sp(
- FindTargetModuleForImageInfo(image_infos[idx], true, NULL));
-
- if (image_module_sp) {
- ObjectFile *objfile = image_module_sp->GetObjectFile();
- if (objfile) {
- SectionList *sections = objfile->GetSectionList();
- if (sections) {
- ConstString commpage_dbstr("__commpage");
- Section *commpage_section =
- sections->FindSectionByName(commpage_dbstr).get();
- if (commpage_section) {
- ModuleSpec module_spec(objfile->GetFileSpec(),
- image_infos[idx].GetArchitecture());
- module_spec.GetObjectName() = commpage_dbstr;
- ModuleSP commpage_image_module_sp(
- target_images.FindFirstModule(module_spec));
- if (!commpage_image_module_sp) {
- module_spec.SetObjectOffset(objfile->GetFileOffset() +
- commpage_section->GetFileOffset());
- module_spec.SetObjectSize(objfile->GetByteSize());
- commpage_image_module_sp = target.GetSharedModule(module_spec);
- if (!commpage_image_module_sp ||
- commpage_image_module_sp->GetObjectFile() == NULL) {
- commpage_image_module_sp = m_process->ReadModuleFromMemory(
- image_infos[idx].file_spec, image_infos[idx].address);
- // Always load a memory image right away in the target in case
- // we end up trying to read the symbol table from memory... The
- // __LINKEDIT will need to be mapped so we can figure out where
- // the symbol table bits are...
- bool changed = false;
- UpdateImageLoadAddress(commpage_image_module_sp.get(),
- image_infos[idx]);
- target.GetImages().Append(commpage_image_module_sp);
- if (changed) {
- image_infos[idx].load_stop_id = m_process->GetStopID();
- loaded_module_list.AppendIfNeeded(commpage_image_module_sp);
- }
- }
- }
- }
- }
- }
-
- // UpdateImageLoadAddress will return true if any segments change load
- // address. We need to check this so we don't mention that all loaded
- // shared libraries are newly loaded each time we hit out dyld breakpoint
- // since dyld will list all shared libraries each time.
- if (UpdateImageLoadAddress(image_module_sp.get(), image_infos[idx])) {
- target_images.AppendIfNeeded(image_module_sp);
- loaded_module_list.AppendIfNeeded(image_module_sp);
- }
- }
- }
-
- if (loaded_module_list.GetSize() > 0) {
- if (log)
- loaded_module_list.LogUUIDAndPaths(log,
- "DynamicLoaderDarwin::ModulesDidLoad");
- m_process->GetTarget().ModulesDidLoad(loaded_module_list);
- }
- return true;
-}
-
-//----------------------------------------------------------------------
-// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
-// functions written in hand-written assembly, and also have hand-written
-// unwind information in the eh_frame section. Normally we prefer analyzing
-// the assembly instructions of a currently executing frame to unwind from that
-// frame -- but on hand-written functions this profiling can fail. We should
-// use the eh_frame instructions for these functions all the time.
-//
-// As an aside, it would be better if the eh_frame entries had a flag (or were
-// extensible so they could have an Apple-specific flag) which indicates that
-// the instructions are asynchronous -- accurate at every instruction, instead
-// of our normal default assumption that they are not.
-//----------------------------------------------------------------------
-
-bool DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo(SymbolContext &sym_ctx) {
- ModuleSP module_sp;
- if (sym_ctx.symbol) {
- module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
- }
- if (module_sp.get() == NULL && sym_ctx.function) {
- module_sp =
- sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
- }
- if (module_sp.get() == NULL)
- return false;
-
- ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
- return objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary(module_sp);
-}
-
-//----------------------------------------------------------------------
-// Dump a Segment to the file handle provided.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwin::Segment::PutToLog(Log *log,
- lldb::addr_t slide) const {
- if (log) {
- if (slide == 0)
- log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
- name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize);
- else
- log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
- ") slide = 0x%" PRIx64,
- name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize,
- slide);
- }
-}
-
-const DynamicLoaderDarwin::Segment *
-DynamicLoaderDarwin::ImageInfo::FindSegment(const ConstString &name) const {
- const size_t num_segments = segments.size();
- for (size_t i = 0; i < num_segments; ++i) {
- if (segments[i].name == name)
- return &segments[i];
- }
- return NULL;
-}
-
-//----------------------------------------------------------------------
-// Dump an image info structure to the file handle provided.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const {
- if (!log)
- return;
- if (address == LLDB_INVALID_ADDRESS) {
- LLDB_LOG(log, "modtime={0:x+8} uuid={1} path='{2}' (UNLOADED)", mod_date,
- uuid.GetAsString(), file_spec.GetPath());
- } else {
- LLDB_LOG(log, "address={0:x+16} modtime={1:x+8} uuid={2} path='{3}'",
- address, mod_date, uuid.GetAsString(), file_spec.GetPath());
- for (uint32_t i = 0; i < segments.size(); ++i)
- segments[i].PutToLog(log, slide);
- }
-}
-
-void DynamicLoaderDarwin::PrivateInitialize(Process *process) {
- DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__,
- StateAsCString(m_process->GetState()));
- Clear(true);
- m_process = process;
- m_process->GetTarget().ClearAllLoadedSections();
-}
-
-//----------------------------------------------------------------------
-// Member function that gets called when the process state changes.
-//----------------------------------------------------------------------
-void DynamicLoaderDarwin::PrivateProcessStateChanged(Process *process,
- StateType state) {
- DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__,
- StateAsCString(state));
- switch (state) {
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear(false);
- break;
-
- case eStateStopped:
- // Keep trying find dyld and set our notification breakpoint each time we
- // stop until we succeed
- if (!DidSetNotificationBreakpoint() && m_process->IsAlive()) {
- if (NeedToDoInitialImageFetch())
- DoInitialImageFetch();
-
- SetNotificationBreakpoint();
- }
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
- }
-}
-
-ThreadPlanSP
-DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
- bool stop_others) {
- ThreadPlanSP thread_plan_sp;
- StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &current_context =
- current_frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *current_symbol = current_context.symbol;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- TargetSP target_sp(thread.CalculateTarget());
-
- if (current_symbol != NULL) {
- std::vector<Address> addresses;
-
- if (current_symbol->IsTrampoline()) {
- const ConstString &trampoline_name = current_symbol->GetMangled().GetName(
- current_symbol->GetLanguage(), Mangled::ePreferMangled);
-
- if (trampoline_name) {
- const ModuleList &images = target_sp->GetImages();
-
- SymbolContextList code_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode,
- code_symbols);
- size_t num_code_symbols = code_symbols.GetSize();
-
- if (num_code_symbols > 0) {
- for (uint32_t i = 0; i < num_code_symbols; i++) {
- SymbolContext context;
- AddressRange addr_range;
- if (code_symbols.GetContextAtIndex(i, context)) {
- context.GetAddressRange(eSymbolContextEverything, 0, false,
- addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log) {
- addr_t load_addr =
- addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf("Found a trampoline target symbol at 0x%" PRIx64
- ".",
- load_addr);
- }
- }
- }
- }
-
- SymbolContextList reexported_symbols;
- images.FindSymbolsWithNameAndType(
- trampoline_name, eSymbolTypeReExported, reexported_symbols);
- size_t num_reexported_symbols = reexported_symbols.GetSize();
- if (num_reexported_symbols > 0) {
- for (uint32_t i = 0; i < num_reexported_symbols; i++) {
- SymbolContext context;
- if (reexported_symbols.GetContextAtIndex(i, context)) {
- if (context.symbol) {
- Symbol *actual_symbol =
- context.symbol->ResolveReExportedSymbol(*target_sp.get());
- if (actual_symbol) {
- const Address actual_symbol_addr =
- actual_symbol->GetAddress();
- if (actual_symbol_addr.IsValid()) {
- addresses.push_back(actual_symbol_addr);
- if (log) {
- lldb::addr_t load_addr =
- actual_symbol_addr.GetLoadAddress(target_sp.get());
- log->Printf(
- "Found a re-exported symbol: %s at 0x%" PRIx64 ".",
- actual_symbol->GetName().GetCString(), load_addr);
- }
- }
- }
- }
- }
- }
- }
-
- SymbolContextList indirect_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver,
- indirect_symbols);
- size_t num_indirect_symbols = indirect_symbols.GetSize();
- if (num_indirect_symbols > 0) {
- for (uint32_t i = 0; i < num_indirect_symbols; i++) {
- SymbolContext context;
- AddressRange addr_range;
- if (indirect_symbols.GetContextAtIndex(i, context)) {
- context.GetAddressRange(eSymbolContextEverything, 0, false,
- addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log) {
- addr_t load_addr =
- addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf("Found an indirect target symbol at 0x%" PRIx64 ".",
- load_addr);
- }
- }
- }
- }
- }
- } else if (current_symbol->GetType() == eSymbolTypeReExported) {
- // I am not sure we could ever end up stopped AT a re-exported symbol.
- // But just in case:
-
- const Symbol *actual_symbol =
- current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
- if (actual_symbol) {
- Address target_addr(actual_symbol->GetAddress());
- if (target_addr.IsValid()) {
- if (log)
- log->Printf(
- "Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64
- ".",
- current_symbol->GetName().GetCString(),
- actual_symbol->GetName().GetCString(),
- target_addr.GetLoadAddress(target_sp.get()));
- addresses.push_back(target_addr.GetLoadAddress(target_sp.get()));
- }
- }
- }
-
- if (addresses.size() > 0) {
- // First check whether any of the addresses point to Indirect symbols,
- // and if they do, resolve them:
- std::vector<lldb::addr_t> load_addrs;
- for (Address address : addresses) {
- Symbol *symbol = address.CalculateSymbolContextSymbol();
- if (symbol && symbol->IsIndirect()) {
- Status error;
- Address symbol_address = symbol->GetAddress();
- addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(
- &symbol_address, error);
- if (error.Success()) {
- load_addrs.push_back(resolved_addr);
- if (log)
- log->Printf("ResolveIndirectFunction found resolved target for "
- "%s at 0x%" PRIx64 ".",
- symbol->GetName().GetCString(), resolved_addr);
- }
- } else {
- load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
- }
- }
- thread_plan_sp.reset(
- new ThreadPlanRunToAddress(thread, load_addrs, stop_others));
- }
- } else {
- if (log)
- log->Printf("Could not find symbol for step through.");
- }
-
- return thread_plan_sp;
-}
-
-size_t DynamicLoaderDarwin::FindEquivalentSymbols(
- lldb_private::Symbol *original_symbol, lldb_private::ModuleList &images,
- lldb_private::SymbolContextList &equivalent_symbols) {
- const ConstString &trampoline_name = original_symbol->GetMangled().GetName(
- original_symbol->GetLanguage(), Mangled::ePreferMangled);
- if (!trampoline_name)
- return 0;
-
- size_t initial_size = equivalent_symbols.GetSize();
-
- static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
- std::string equivalent_regex_buf("^");
- equivalent_regex_buf.append(trampoline_name.GetCString());
- equivalent_regex_buf.append(resolver_name_regex);
-
- RegularExpression equivalent_name_regex(equivalent_regex_buf);
- const bool append = true;
- images.FindSymbolsMatchingRegExAndType(equivalent_name_regex, eSymbolTypeCode,
- equivalent_symbols, append);
-
- return equivalent_symbols.GetSize() - initial_size;
-}
-
-lldb::ModuleSP DynamicLoaderDarwin::GetPThreadLibraryModule() {
- ModuleSP module_sp = m_libpthread_module_wp.lock();
- if (!module_sp) {
- SymbolContextList sc_list;
- ModuleSpec module_spec;
- module_spec.GetFileSpec().GetFilename().SetCString(
- "libsystem_pthread.dylib");
- ModuleList module_list;
- if (m_process->GetTarget().GetImages().FindModules(module_spec,
- module_list)) {
- if (module_list.GetSize() == 1) {
- module_sp = module_list.GetModuleAtIndex(0);
- if (module_sp)
- m_libpthread_module_wp = module_sp;
- }
- }
- }
- return module_sp;
-}
-
-Address DynamicLoaderDarwin::GetPthreadSetSpecificAddress() {
- if (!m_pthread_getspecific_addr.IsValid()) {
- ModuleSP module_sp = GetPThreadLibraryModule();
- if (module_sp) {
- lldb_private::SymbolContextList sc_list;
- module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"),
- eSymbolTypeCode, sc_list);
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc)) {
- if (sc.symbol)
- m_pthread_getspecific_addr = sc.symbol->GetAddress();
- }
- }
- }
- return m_pthread_getspecific_addr;
-}
-
-lldb::addr_t
-DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp,
- const lldb::ThreadSP thread_sp,
- lldb::addr_t tls_file_addr) {
- if (!thread_sp || !module_sp)
- return LLDB_INVALID_ADDRESS;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- const uint32_t addr_size = m_process->GetAddressByteSize();
- uint8_t buf[sizeof(lldb::addr_t) * 3];
-
- lldb_private::Address tls_addr;
- if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr)) {
- Status error;
- const size_t tsl_data_size = addr_size * 3;
- Target &target = m_process->GetTarget();
- if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) ==
- tsl_data_size) {
- const ByteOrder byte_order = m_process->GetByteOrder();
- DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
- lldb::offset_t offset = addr_size; // Skip the first pointer
- const lldb::addr_t pthread_key = data.GetAddress(&offset);
- const lldb::addr_t tls_offset = data.GetAddress(&offset);
- if (pthread_key != 0) {
- // First check to see if we have already figured out the location of
- // TLS data for the pthread_key on a specific thread yet. If we have we
- // can re-use it since its location will not change unless the process
- // execs.
- const tid_t tid = thread_sp->GetID();
- auto tid_pos = m_tid_to_tls_map.find(tid);
- if (tid_pos != m_tid_to_tls_map.end()) {
- auto tls_pos = tid_pos->second.find(pthread_key);
- if (tls_pos != tid_pos->second.end()) {
- return tls_pos->second + tls_offset;
- }
- }
- StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
- if (frame_sp) {
- ClangASTContext *clang_ast_context =
- target.GetScratchClangASTContext();
-
- if (!clang_ast_context)
- return LLDB_INVALID_ADDRESS;
-
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
- if (pthread_getspecific_addr.IsValid()) {
- EvaluateExpressionOptions options;
-
- lldb::ThreadPlanSP thread_plan_sp(new ThreadPlanCallFunction(
- *thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
- llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
-
- DiagnosticManager execution_errors;
- ExecutionContext exe_ctx(thread_sp);
- lldb::ExpressionResults results = m_process->RunThreadPlan(
- exe_ctx, thread_plan_sp, options, execution_errors);
-
- if (results == lldb::eExpressionCompleted) {
- lldb::ValueObjectSP result_valobj_sp =
- thread_plan_sp->GetReturnValueObject();
- if (result_valobj_sp) {
- const lldb::addr_t pthread_key_data =
- result_valobj_sp->GetValueAsUnsigned(0);
- if (pthread_key_data) {
- m_tid_to_tls_map[tid].insert(
- std::make_pair(pthread_key, pthread_key_data));
- return pthread_key_data + tls_offset;
- }
- }
- }
- }
- }
- }
- }
- }
- return LLDB_INVALID_ADDRESS;
-}
-
-bool DynamicLoaderDarwin::UseDYLDSPI(Process *process) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- bool use_new_spi_interface = false;
-
- llvm::VersionTuple version = process->GetHostOSVersion();
- if (!version.empty()) {
- const llvm::Triple::OSType os_type =
- process->GetTarget().GetArchitecture().GetTriple().getOS();
-
- // macOS 10.12 and newer
- if (os_type == llvm::Triple::MacOSX &&
- version >= llvm::VersionTuple(10, 12))
- use_new_spi_interface = true;
-
- // iOS 10 and newer
- if (os_type == llvm::Triple::IOS && version >= llvm::VersionTuple(10))
- use_new_spi_interface = true;
-
- // tvOS 10 and newer
- if (os_type == llvm::Triple::TvOS && version >= llvm::VersionTuple(10))
- use_new_spi_interface = true;
-
- // watchOS 3 and newer
- if (os_type == llvm::Triple::WatchOS && version >= llvm::VersionTuple(3))
- use_new_spi_interface = true;
-
- // NEED_BRIDGEOS_TRIPLE // Any BridgeOS
- // NEED_BRIDGEOS_TRIPLE if (os_type == llvm::Triple::BridgeOS)
- // NEED_BRIDGEOS_TRIPLE use_new_spi_interface = true;
- }
-
- if (log) {
- if (use_new_spi_interface)
- log->Printf(
- "DynamicLoaderDarwin::UseDYLDSPI: Use new DynamicLoader plugin");
- else
- log->Printf(
- "DynamicLoaderDarwin::UseDYLDSPI: Use old DynamicLoader plugin");
- }
- return use_new_spi_interface;
-}
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
deleted file mode 100644
index 690253ba5ff2c..0000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
+++ /dev/null
@@ -1,241 +0,0 @@
-//===-- DynamicLoaderDarwin.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_DynamicLoaderDarwin_h_
-#define liblldb_DynamicLoaderDarwin_h_
-
-#include <map>
-#include <mutex>
-#include <vector>
-
-#include "lldb/Host/SafeMachO.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/StructuredData.h"
-#include "lldb/Utility/UUID.h"
-
-#include "llvm/ADT/Triple.h"
-
-namespace lldb_private {
-
-class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
-public:
- DynamicLoaderDarwin(lldb_private::Process *process);
-
- virtual ~DynamicLoaderDarwin() override;
-
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void DidAttach() override;
-
- void DidLaunch() override;
-
- lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
-
- size_t FindEquivalentSymbols(
- lldb_private::Symbol *original_symbol,
- lldb_private::ModuleList &module_list,
- lldb_private::SymbolContextList &equivalent_symbols) override;
-
- lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
- const lldb::ThreadSP thread,
- lldb::addr_t tls_file_addr) override;
-
- bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
-
- virtual void DoInitialImageFetch() = 0;
-
- virtual bool NeedToDoInitialImageFetch() = 0;
-
-protected:
- void PrivateInitialize(lldb_private::Process *process);
-
- void PrivateProcessStateChanged(lldb_private::Process *process,
- lldb::StateType state);
-
- void Clear(bool clear_process);
-
- // Clear method for classes derived from this one
- virtual void DoClear() = 0;
-
- void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
-
- lldb::ModuleSP GetDYLDModule();
-
- class Segment {
- public:
- Segment()
- : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
- filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
-
- lldb_private::ConstString name;
- lldb::addr_t vmaddr;
- lldb::addr_t vmsize;
- lldb::addr_t fileoff;
- lldb::addr_t filesize;
- uint32_t maxprot;
- uint32_t initprot;
- uint32_t nsects;
- uint32_t flags;
-
- bool operator==(const Segment &rhs) const {
- return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
- }
-
- void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
- };
-
- struct ImageInfo {
- lldb::addr_t address; // Address of mach header for this dylib
- lldb::addr_t slide; // The amount to slide all segments by if there is a
- // global slide.
- lldb::addr_t mod_date; // Modification date for this dylib
- lldb_private::FileSpec file_spec; // Resolved path for this dylib
- lldb_private::UUID
- uuid; // UUID for this dylib if it has one, else all zeros
- llvm::MachO::mach_header header; // The mach header for this image
- std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for
- // this executable (from memory of inferior)
- uint32_t load_stop_id; // The process stop ID that the sections for this
- // image were loaded
- llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
- std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
-
- ImageInfo()
- : address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
- uuid(), header(), segments(), load_stop_id(0),
- os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
-
- void Clear(bool load_cmd_data_only) {
- if (!load_cmd_data_only) {
- address = LLDB_INVALID_ADDRESS;
- slide = 0;
- mod_date = 0;
- file_spec.Clear();
- ::memset(&header, 0, sizeof(header));
- }
- uuid.Clear();
- segments.clear();
- load_stop_id = 0;
- os_type = llvm::Triple::OSType::UnknownOS;
- min_version_os_sdk.clear();
- }
-
- bool operator==(const ImageInfo &rhs) const {
- return address == rhs.address && slide == rhs.slide &&
- mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
- uuid == rhs.uuid &&
- memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
- segments == rhs.segments && os_type == rhs.os_type;
- }
-
- bool UUIDValid() const { return uuid.IsValid(); }
-
- uint32_t GetAddressByteSize() {
- if (header.cputype) {
- if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
- return 8;
- else
- return 4;
- }
- return 0;
- }
-
- lldb_private::ArchSpec GetArchitecture() const {
- return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
- header.cputype, header.cpusubtype);
- }
-
- const Segment *FindSegment(const lldb_private::ConstString &name) const;
-
- void PutToLog(lldb_private::Log *log) const;
-
- typedef std::vector<ImageInfo> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- };
-
- bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
-
- bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
-
- lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
- bool can_create,
- bool *did_create_ptr);
-
- void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
-
- void UnloadAllImages();
-
- virtual bool SetNotificationBreakpoint() = 0;
-
- virtual void ClearNotificationBreakpoint() = 0;
-
- virtual bool DidSetNotificationBreakpoint() = 0;
-
- typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
- typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
-
- std::recursive_mutex &GetMutex() const { return m_mutex; }
-
- lldb::ModuleSP GetPThreadLibraryModule();
-
- lldb_private::Address GetPthreadSetSpecificAddress();
-
- bool JSONImageInformationIntoImageInfo(
- lldb_private::StructuredData::ObjectSP image_details,
- ImageInfo::collection &image_infos);
-
- // If image_infos contains / may contain dyld or executable image, call this
- // method
- // to keep our internal record keeping of the special binaries up-to-date.
- void
- UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
-
- // if image_info is a dyld binary, call this method
- void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
-
- // If image_infos contains / may contain executable image, call this method
- // to keep our internal record keeping of the special dyld binary up-to-date.
- void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
-
- bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
-
- // Whether we should use the new dyld SPI to get shared library information,
- // or read
- // it directly out of the dyld_all_image_infos. Whether we use the (newer)
- // DynamicLoaderMacOS
- // plugin or the (older) DynamicLoaderMacOSX plugin.
- static bool UseDYLDSPI(lldb_private::Process *process);
-
- lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
- // matches the process
- lldb::ModuleWP m_libpthread_module_wp;
- lldb_private::Address m_pthread_getspecific_addr;
- ThreadIDToTLSMap m_tid_to_tls_map;
- ImageInfo::collection
- m_dyld_image_infos; // Current shared libraries information
- uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
- // "m_dyld_image_infos" is valid for
- ImageInfo m_dyld;
- mutable std::recursive_mutex m_mutex;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_DynamicLoaderDarwin_h_
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
deleted file mode 100644
index 1ff0ec2c79377..0000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ /dev/null
@@ -1,548 +0,0 @@
-//===-- DynamicLoaderMacOS.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/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
-#include "lldb/Target/ABI.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-
-#include "DynamicLoaderDarwin.h"
-#include "DynamicLoaderMacOS.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into the plugin
-// info class that gets handed out by the plugin factory and allows the lldb to
-// instantiate an instance of this class.
-//----------------------------------------------------------------------
-DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
- bool force) {
- bool create = force;
- if (!create) {
- create = true;
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module) {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file) {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create) {
- const llvm::Triple &triple_ref =
- process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS()) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
- }
-
- if (!UseDYLDSPI(process)) {
- create = false;
- }
-
- if (create)
- return new DynamicLoaderMacOS(process);
- return NULL;
-}
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-DynamicLoaderMacOS::DynamicLoaderMacOS(Process *process)
- : DynamicLoaderDarwin(process), m_image_infos_stop_id(UINT32_MAX),
- m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
- m_maybe_image_infos_address(LLDB_INVALID_ADDRESS) {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-DynamicLoaderMacOS::~DynamicLoaderMacOS() {
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID(m_break_id);
-}
-
-bool DynamicLoaderMacOS::ProcessDidExec() {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- bool did_exec = false;
- if (m_process) {
- // If we are stopped after an exec, we will have only one thread...
- if (m_process->GetThreadList().GetSize() == 1) {
- // Maybe we still have an image infos address around? If so see
- // if that has changed, and if so we have exec'ed.
- if (m_maybe_image_infos_address != LLDB_INVALID_ADDRESS) {
- lldb::addr_t image_infos_address = m_process->GetImageInfoAddress();
- if (image_infos_address != m_maybe_image_infos_address) {
- // We don't really have to reset this here, since we are going to
- // call DoInitialImageFetch right away to handle the exec. But in
- // case anybody looks at it in the meantime, it can't hurt.
- m_maybe_image_infos_address = image_infos_address;
- did_exec = true;
- }
- }
-
- if (!did_exec) {
- // See if we are stopped at '_dyld_start'
- ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
- if (thread_sp) {
- lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
- if (frame_sp) {
- const Symbol *symbol =
- frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (symbol) {
- if (symbol->GetName() == ConstString("_dyld_start"))
- did_exec = true;
- }
- }
- }
- }
- }
- }
-
- if (did_exec) {
- m_libpthread_module_wp.reset();
- m_pthread_getspecific_addr.Clear();
- }
- return did_exec;
-}
-
-//----------------------------------------------------------------------
-// Clear out the state of this class.
-//----------------------------------------------------------------------
-void DynamicLoaderMacOS::DoClear() {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID(m_break_id);
-
- m_break_id = LLDB_INVALID_BREAK_ID;
-}
-
-//----------------------------------------------------------------------
-// Check if we have found DYLD yet
-//----------------------------------------------------------------------
-bool DynamicLoaderMacOS::DidSetNotificationBreakpoint() {
- return LLDB_BREAK_ID_IS_VALID(m_break_id);
-}
-
-void DynamicLoaderMacOS::ClearNotificationBreakpoint() {
- if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
- m_process->GetTarget().RemoveBreakpointByID(m_break_id);
- m_break_id = LLDB_INVALID_BREAK_ID;
- }
-}
-
-//----------------------------------------------------------------------
-// Try and figure out where dyld is by first asking the Process if it knows
-// (which currently calls down in the lldb::Process to get the DYLD info
-// (available on SnowLeopard only). If that fails, then check in the default
-// addresses.
-//----------------------------------------------------------------------
-void DynamicLoaderMacOS::DoInitialImageFetch() {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- // Remove any binaries we pre-loaded in the Target before
- // launching/attaching. If the same binaries are present in the process,
- // we'll get them from the shared module cache, we won't need to re-load them
- // from disk.
- UnloadAllImages();
-
- StructuredData::ObjectSP all_image_info_json_sp(
- m_process->GetLoadedDynamicLibrariesInfos());
- ImageInfo::collection image_infos;
- if (all_image_info_json_sp.get() &&
- all_image_info_json_sp->GetAsDictionary() &&
- all_image_info_json_sp->GetAsDictionary()->HasKey("images") &&
- all_image_info_json_sp->GetAsDictionary()
- ->GetValueForKey("images")
- ->GetAsArray()) {
- if (JSONImageInformationIntoImageInfo(all_image_info_json_sp,
- image_infos)) {
- if (log)
- log->Printf("Initial module fetch: Adding %" PRId64 " modules.\n",
- (uint64_t)image_infos.size());
-
- UpdateSpecialBinariesFromNewImageInfos(image_infos);
- AddModulesUsingImageInfos(image_infos);
- }
- }
-
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- m_maybe_image_infos_address = m_process->GetImageInfoAddress();
-}
-
-bool DynamicLoaderMacOS::NeedToDoInitialImageFetch() { return true; }
-
-//----------------------------------------------------------------------
-// Static callback function that gets called when our DYLD notification
-// breakpoint gets hit. We update all of our image infos and then let our super
-// class DynamicLoader class decide if we should stop or not (based on global
-// preference).
-//----------------------------------------------------------------------
-bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id) {
- // Let the event know that the images have changed
- // DYLD passes three arguments to the notification breakpoint.
- // Arg1: enum dyld_notify_mode mode - 0 = adding, 1 = removing, 2 = remove
- // all Arg2: unsigned long icount - Number of shared libraries
- // added/removed Arg3: uint64_t mach_headers[] - Array of load addresses
- // of binaries added/removed
-
- DynamicLoaderMacOS *dyld_instance = (DynamicLoaderMacOS *)baton;
-
- ExecutionContext exe_ctx(context->exe_ctx_ref);
- Process *process = exe_ctx.GetProcessPtr();
-
- // This is a sanity check just in case this dyld_instance is an old dyld
- // plugin's breakpoint still lying around.
- if (process != dyld_instance->m_process)
- return false;
-
- if (dyld_instance->m_image_infos_stop_id != UINT32_MAX &&
- process->GetStopID() < dyld_instance->m_image_infos_stop_id) {
- return false;
- }
-
- const lldb::ABISP &abi = process->GetABI();
- if (abi) {
- // Build up the value array to store the three arguments given above, then
- // get the values from the ABI:
-
- ClangASTContext *clang_ast_context =
- process->GetTarget().GetScratchClangASTContext();
- ValueList argument_values;
-
- Value mode_value; // enum dyld_notify_mode { dyld_notify_adding=0,
- // dyld_notify_removing=1, dyld_notify_remove_all=2 };
- Value count_value; // unsigned long count
- Value headers_value; // uint64_t machHeaders[] (aka void*)
-
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- CompilerType clang_uint32_type =
- clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
- lldb::eEncodingUint, 32);
- CompilerType clang_uint64_type =
- clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
- lldb::eEncodingUint, 32);
-
- mode_value.SetValueType(Value::eValueTypeScalar);
- mode_value.SetCompilerType(clang_uint32_type);
-
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 4) {
- count_value.SetValueType(Value::eValueTypeScalar);
- count_value.SetCompilerType(clang_uint32_type);
- } else {
- count_value.SetValueType(Value::eValueTypeScalar);
- count_value.SetCompilerType(clang_uint64_type);
- }
-
- headers_value.SetValueType(Value::eValueTypeScalar);
- headers_value.SetCompilerType(clang_void_ptr_type);
-
- argument_values.PushValue(mode_value);
- argument_values.PushValue(count_value);
- argument_values.PushValue(headers_value);
-
- if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
- uint32_t dyld_mode =
- argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
- if (dyld_mode != static_cast<uint32_t>(-1)) {
- // Okay the mode was right, now get the number of elements, and the
- // array of new elements...
- uint32_t image_infos_count =
- argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
- if (image_infos_count != static_cast<uint32_t>(-1)) {
- addr_t header_array =
- argument_values.GetValueAtIndex(2)->GetScalar().ULongLong(-1);
- if (header_array != static_cast<uint64_t>(-1)) {
- std::vector<addr_t> image_load_addresses;
- for (uint64_t i = 0; i < image_infos_count; i++) {
- Status error;
- addr_t addr = process->ReadUnsignedIntegerFromMemory(
- header_array + (8 * i), 8, LLDB_INVALID_ADDRESS, error);
- if (addr != LLDB_INVALID_ADDRESS) {
- image_load_addresses.push_back(addr);
- }
- }
- if (dyld_mode == 0) {
- // dyld_notify_adding
- dyld_instance->AddBinaries(image_load_addresses);
- } else if (dyld_mode == 1) {
- // dyld_notify_removing
- dyld_instance->UnloadImages(image_load_addresses);
- } else if (dyld_mode == 2) {
- // dyld_notify_remove_all
- dyld_instance->UnloadAllImages();
- }
- }
- }
- }
- }
- } else {
- process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
- "No ABI plugin located for triple %s -- shared libraries will not be "
- "registered!\n",
- process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
- }
-
- // Return true to stop the target, false to just let the target run
- return dyld_instance->GetStopWhenImagesChange();
-}
-
-void DynamicLoaderMacOS::AddBinaries(
- const std::vector<lldb::addr_t> &load_addresses) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- ImageInfo::collection image_infos;
-
- if (log)
- log->Printf("Adding %" PRId64 " modules.", (uint64_t)load_addresses.size());
- StructuredData::ObjectSP binaries_info_sp =
- m_process->GetLoadedDynamicLibrariesInfos(load_addresses);
- if (binaries_info_sp.get() && binaries_info_sp->GetAsDictionary() &&
- binaries_info_sp->GetAsDictionary()->HasKey("images") &&
- binaries_info_sp->GetAsDictionary()
- ->GetValueForKey("images")
- ->GetAsArray() &&
- binaries_info_sp->GetAsDictionary()
- ->GetValueForKey("images")
- ->GetAsArray()
- ->GetSize() == load_addresses.size()) {
- if (JSONImageInformationIntoImageInfo(binaries_info_sp, image_infos)) {
- UpdateSpecialBinariesFromNewImageInfos(image_infos);
- AddModulesUsingImageInfos(image_infos);
- }
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- }
-}
-
-// Dump the _dyld_all_image_infos members and all current image infos that we
-// have parsed to the file handle provided.
-//----------------------------------------------------------------------
-void DynamicLoaderMacOS::PutToLog(Log *log) const {
- if (log == NULL)
- return;
-}
-
-bool DynamicLoaderMacOS::SetNotificationBreakpoint() {
- if (m_break_id == LLDB_INVALID_BREAK_ID) {
- ConstString g_symbol_name("_dyld_debugger_notification");
- const Symbol *symbol = nullptr;
- ModuleSP dyld_sp(GetDYLDModule());
- if (dyld_sp) {
- symbol = dyld_sp->FindFirstSymbolWithNameAndType(g_symbol_name,
- eSymbolTypeCode);
- }
- if (symbol &&
- (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
- addr_t symbol_address =
- symbol->GetAddressRef().GetOpcodeLoadAddress(&m_process->GetTarget());
- if (symbol_address != LLDB_INVALID_ADDRESS) {
- bool internal = true;
- bool hardware = false;
- Breakpoint *breakpoint =
- m_process->GetTarget()
- .CreateBreakpoint(symbol_address, internal, hardware)
- .get();
- breakpoint->SetCallback(DynamicLoaderMacOS::NotifyBreakpointHit, this,
- true);
- breakpoint->SetBreakpointKind("shared-library-event");
- m_break_id = breakpoint->GetID();
- }
- }
- }
- return m_break_id != LLDB_INVALID_BREAK_ID;
-}
-
-addr_t
-DynamicLoaderMacOS::GetDyldLockVariableAddressFromModule(Module *module) {
- SymbolContext sc;
- SymbolVendor *sym_vendor = module->GetSymbolVendor();
- Target &target = m_process->GetTarget();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab) {
- std::vector<uint32_t> match_indexes;
- ConstString g_symbol_name("_dyld_global_lock_held");
- uint32_t num_matches = 0;
- num_matches =
- symtab->AppendSymbolIndexesWithName(g_symbol_name, match_indexes);
- if (num_matches == 1) {
- Symbol *symbol = symtab->SymbolAtIndex(match_indexes[0]);
- if (symbol &&
- (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
- return symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
- }
- }
- }
- }
- return LLDB_INVALID_ADDRESS;
-}
-
-// Look for this symbol:
-//
-// int __attribute__((visibility("hidden"))) _dyld_global_lock_held =
-// 0;
-//
-// in libdyld.dylib.
-Status DynamicLoaderMacOS::CanLoadImage() {
- Status error;
- addr_t symbol_address = LLDB_INVALID_ADDRESS;
- Target &target = m_process->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- ConstString g_libdyld_name("libdyld.dylib");
-
- // Find any modules named "libdyld.dylib" and look for the symbol there first
- for (size_t i = 0; i < num_modules; i++) {
- Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
- if (module_pointer) {
- if (module_pointer->GetFileSpec().GetFilename() == g_libdyld_name) {
- symbol_address = GetDyldLockVariableAddressFromModule(module_pointer);
- if (symbol_address != LLDB_INVALID_ADDRESS)
- break;
- }
- }
- }
-
- // Search through all modules looking for the symbol in them
- if (symbol_address == LLDB_INVALID_ADDRESS) {
- for (size_t i = 0; i < num_modules; i++) {
- Module *module_pointer =
- target_modules.GetModulePointerAtIndexUnlocked(i);
- if (module_pointer) {
- addr_t symbol_address =
- GetDyldLockVariableAddressFromModule(module_pointer);
- if (symbol_address != LLDB_INVALID_ADDRESS)
- break;
- }
- }
- }
-
- // Default assumption is that it is OK to load images. Only say that we
- // cannot load images if we find the symbol in libdyld and it indicates that
- // we cannot.
-
- if (symbol_address != LLDB_INVALID_ADDRESS) {
- {
- int lock_held =
- m_process->ReadUnsignedIntegerFromMemory(symbol_address, 4, 0, error);
- if (lock_held != 0) {
- error.SetErrorString("dyld lock held - unsafe to load images.");
- }
- }
- } else {
- // If we were unable to find _dyld_global_lock_held in any modules, or it
- // is not loaded into memory yet, we may be at process startup (sitting at
- // _dyld_start) - so we should not allow dlopen calls. But if we found more
- // than one module then we are clearly past _dyld_start so in that case
- // we'll default to "it's safe".
- if (num_modules <= 1)
- error.SetErrorString("could not find the dyld library or "
- "the dyld lock symbol");
- }
- return error;
-}
-
-bool DynamicLoaderMacOS::GetSharedCacheInformation(
- lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
- LazyBool &private_shared_cache) {
- base_address = LLDB_INVALID_ADDRESS;
- uuid.Clear();
- using_shared_cache = eLazyBoolCalculate;
- private_shared_cache = eLazyBoolCalculate;
-
- if (m_process) {
- StructuredData::ObjectSP info = m_process->GetSharedCacheInfo();
- StructuredData::Dictionary *info_dict = nullptr;
- if (info.get() && info->GetAsDictionary()) {
- info_dict = info->GetAsDictionary();
- }
-
- // {"shared_cache_base_address":140735683125248,"shared_cache_uuid
- // ":"DDB8D70C-
- // C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false}
-
- if (info_dict && info_dict->HasKey("shared_cache_uuid") &&
- info_dict->HasKey("no_shared_cache") &&
- info_dict->HasKey("shared_cache_base_address")) {
- base_address = info_dict->GetValueForKey("shared_cache_base_address")
- ->GetIntegerValue(LLDB_INVALID_ADDRESS);
- std::string uuid_str =
- info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue();
- if (!uuid_str.empty())
- uuid.SetFromStringRef(uuid_str);
- if (!info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue())
- using_shared_cache = eLazyBoolYes;
- else
- using_shared_cache = eLazyBoolNo;
- if (info_dict->GetValueForKey("shared_cache_private_cache")
- ->GetBooleanValue())
- private_shared_cache = eLazyBoolYes;
- else
- private_shared_cache = eLazyBoolNo;
-
- return true;
- }
- }
- return false;
-}
-
-void DynamicLoaderMacOS::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
-}
-
-void DynamicLoaderMacOS::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString DynamicLoaderMacOS::GetPluginNameStatic() {
- static ConstString g_name("macos-dyld");
- return g_name;
-}
-
-const char *DynamicLoaderMacOS::GetPluginDescriptionStatic() {
- return "Dynamic loader plug-in that watches for shared library loads/unloads "
- "in MacOSX user processes.";
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString DynamicLoaderMacOS::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t DynamicLoaderMacOS::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
deleted file mode 100644
index 6303c066511c3..0000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===-- DynamicLoaderMacOS.h -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
-// watchOS / BridgeOS)
-// platforms late 2016 and newer, where lldb will call dyld SPI functions to get
-// information about shared libraries, information about the shared cache, and
-// the _dyld_debugger_notification function we put a breakpoint on give us an
-// array of load addresses for solibs loaded and unloaded. The SPI will tell us
-// about both dyld and the executable, in addition to all of the usual solibs.
-
-#ifndef liblldb_DynamicLoaderMacOS_h_
-#define liblldb_DynamicLoaderMacOS_h_
-
-#include <mutex>
-#include <vector>
-
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/StructuredData.h"
-#include "lldb/Utility/UUID.h"
-
-#include "DynamicLoaderDarwin.h"
-
-class DynamicLoaderMacOS : public lldb_private::DynamicLoaderDarwin {
-public:
- DynamicLoaderMacOS(lldb_private::Process *process);
-
- virtual ~DynamicLoaderMacOS() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::DynamicLoader *
- CreateInstance(lldb_private::Process *process, bool force);
-
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- bool ProcessDidExec() override;
-
- lldb_private::Status CanLoadImage() override;
-
- bool GetSharedCacheInformation(
- lldb::addr_t &base_address, lldb_private::UUID &uuid,
- lldb_private::LazyBool &using_shared_cache,
- lldb_private::LazyBool &private_shared_cache) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
-protected:
- void PutToLog(lldb_private::Log *log) const;
-
- void DoInitialImageFetch() override;
-
- bool NeedToDoInitialImageFetch() override;
-
- bool DidSetNotificationBreakpoint() override;
-
- void AddBinaries(const std::vector<lldb::addr_t> &load_addresses);
-
- void DoClear() override;
-
- static bool
- NotifyBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
- bool SetNotificationBreakpoint() override;
-
- void ClearNotificationBreakpoint() override;
-
- void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
-
- lldb::addr_t
- GetDyldLockVariableAddressFromModule(lldb_private::Module *module);
-
- uint32_t m_image_infos_stop_id; // The Stop ID the last time we
- // loaded/unloaded images
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
- lldb::addr_t m_maybe_image_infos_address; // If dyld is still maintaining the
- // all_image_infos address, store it
- // here so we can use it to detect
- // exec's when talking to
- // debugservers that don't support
- // the "reason:exec" annotation.
-
-private:
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOS);
-};
-
-#endif // liblldb_DynamicLoaderMacOS_h_
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
deleted file mode 100644
index ec459a783f944..0000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ /dev/null
@@ -1,1207 +0,0 @@
-//===-- DynamicLoaderMacOSXDYLD.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/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/ABI.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-
-#include "DynamicLoaderDarwin.h"
-#include "DynamicLoaderMacOSXDYLD.h"
-
-//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
-#ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
-
-#ifndef __APPLE__
-#include "Utility/UuidCompatibility.h"
-#else
-#include <uuid/uuid.h>
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into the plugin
-// info class that gets handed out by the plugin factory and allows the lldb to
-// instantiate an instance of this class.
-//----------------------------------------------------------------------
-DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
- bool force) {
- bool create = force;
- if (!create) {
- create = true;
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module) {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file) {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create) {
- const llvm::Triple &triple_ref =
- process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS()) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
- }
-
- if (UseDYLDSPI(process)) {
- create = false;
- }
-
- if (create)
- return new DynamicLoaderMacOSXDYLD(process);
- return NULL;
-}
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD(Process *process)
- : DynamicLoaderDarwin(process),
- m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
- m_dyld_all_image_infos(), m_dyld_all_image_infos_stop_id(UINT32_MAX),
- m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
- m_process_image_addr_is_all_images_infos(false) {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD() {
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID(m_break_id);
-}
-
-bool DynamicLoaderMacOSXDYLD::ProcessDidExec() {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- bool did_exec = false;
- if (m_process) {
- // If we are stopped after an exec, we will have only one thread...
- if (m_process->GetThreadList().GetSize() == 1) {
- // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
- // value differs from the Process' image info address. When a process
- // execs itself it might cause a change if ASLR is enabled.
- const addr_t shlib_addr = m_process->GetImageInfoAddress();
- if (m_process_image_addr_is_all_images_infos &&
- shlib_addr != m_dyld_all_image_infos_addr) {
- // The image info address from the process is the
- // 'dyld_all_image_infos' address and it has changed.
- did_exec = true;
- } else if (!m_process_image_addr_is_all_images_infos &&
- shlib_addr == m_dyld.address) {
- // The image info address from the process is the mach_header address
- // for dyld and it has changed.
- did_exec = true;
- } else {
- // ASLR might be disabled and dyld could have ended up in the same
- // location. We should try and detect if we are stopped at
- // '_dyld_start'
- ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
- if (thread_sp) {
- lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
- if (frame_sp) {
- const Symbol *symbol =
- frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (symbol) {
- if (symbol->GetName() == ConstString("_dyld_start"))
- did_exec = true;
- }
- }
- }
- }
-
- if (did_exec) {
- m_libpthread_module_wp.reset();
- m_pthread_getspecific_addr.Clear();
- }
- }
- }
- return did_exec;
-}
-
-//----------------------------------------------------------------------
-// Clear out the state of this class.
-//----------------------------------------------------------------------
-void DynamicLoaderMacOSXDYLD::DoClear() {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID(m_break_id);
-
- m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
- m_dyld_all_image_infos.Clear();
- m_break_id = LLDB_INVALID_BREAK_ID;
-}
-
-//----------------------------------------------------------------------
-// Check if we have found DYLD yet
-//----------------------------------------------------------------------
-bool DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() {
- return LLDB_BREAK_ID_IS_VALID(m_break_id);
-}
-
-void DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint() {
- if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
- m_process->GetTarget().RemoveBreakpointByID(m_break_id);
- }
-}
-
-//----------------------------------------------------------------------
-// Try and figure out where dyld is by first asking the Process if it knows
-// (which currently calls down in the lldb::Process to get the DYLD info
-// (available on SnowLeopard only). If that fails, then check in the default
-// addresses.
-//----------------------------------------------------------------------
-void DynamicLoaderMacOSXDYLD::DoInitialImageFetch() {
- if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) {
- // Check the image info addr as it might point to the mach header for dyld,
- // or it might point to the dyld_all_image_infos struct
- const addr_t shlib_addr = m_process->GetImageInfoAddress();
- if (shlib_addr != LLDB_INVALID_ADDRESS) {
- ByteOrder byte_order =
- m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint8_t buf[4];
- DataExtractor data(buf, sizeof(buf), byte_order, 4);
- Status error;
- if (m_process->ReadMemory(shlib_addr, buf, 4, error) == 4) {
- lldb::offset_t offset = 0;
- uint32_t magic = data.GetU32(&offset);
- switch (magic) {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- m_process_image_addr_is_all_images_infos = false;
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
- return;
-
- default:
- break;
- }
- }
- // Maybe it points to the all image infos?
- m_dyld_all_image_infos_addr = shlib_addr;
- m_process_image_addr_is_all_images_infos = true;
- }
- }
-
- if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
- if (ReadAllImageInfosStructure()) {
- if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(
- m_dyld_all_image_infos.dyldImageLoadAddress);
- else
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(
- m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
- return;
- }
- }
-
- // Check some default values
- Module *executable = m_process->GetTarget().GetExecutableModulePointer();
-
- if (executable) {
- const ArchSpec &exe_arch = executable->GetArchitecture();
- if (exe_arch.GetAddressByteSize() == 8) {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
- } else if (exe_arch.GetMachine() == llvm::Triple::arm ||
- exe_arch.GetMachine() == llvm::Triple::thumb ||
- exe_arch.GetMachine() == llvm::Triple::aarch64) {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
- } else {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
- }
- }
- return;
-}
-
-//----------------------------------------------------------------------
-// Assume that dyld is in memory at ADDR and try to parse it's load commands
-//----------------------------------------------------------------------
-bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(
- lldb::addr_t addr) {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- DataExtractor data; // Load command data
- static ConstString g_dyld_all_image_infos("dyld_all_image_infos");
- if (ReadMachHeader(addr, &m_dyld.header, &data)) {
- if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER) {
- m_dyld.address = addr;
- ModuleSP dyld_module_sp;
- if (ParseLoadCommands(data, m_dyld, &m_dyld.file_spec)) {
- if (m_dyld.file_spec) {
- UpdateDYLDImageInfoFromNewImageInfo(m_dyld);
- }
- }
- dyld_module_sp = GetDYLDModule();
-
- Target &target = m_process->GetTarget();
-
- if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS &&
- dyld_module_sp.get()) {
- const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType(
- g_dyld_all_image_infos, eSymbolTypeData);
- if (symbol)
- m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target);
- }
-
- // Update all image infos
- InitializeFromAllImageInfos();
-
- // If we didn't have an executable before, but now we do, then the dyld
- // module shared pointer might be unique and we may need to add it again
- // (since Target::SetExecutableModule() will clear the images). So append
- // the dyld module back to the list if it is
- /// unique!
- if (dyld_module_sp) {
- target.GetImages().AppendIfNeeded(dyld_module_sp);
-
- // At this point we should have read in dyld's module, and so we should
- // set breakpoints in it:
- ModuleList modules;
- modules.Append(dyld_module_sp);
- target.ModulesDidLoad(modules);
- SetDYLDModule(dyld_module_sp);
- }
-
- return true;
- }
- }
- return false;
-}
-
-bool DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch() {
- return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
-}
-
-//----------------------------------------------------------------------
-// Static callback function that gets called when our DYLD notification
-// breakpoint gets hit. We update all of our image infos and then let our super
-// class DynamicLoader class decide if we should stop or not (based on global
-// preference).
-//----------------------------------------------------------------------
-bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
- void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id) {
- // Let the event know that the images have changed
- // DYLD passes three arguments to the notification breakpoint.
- // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing Arg2: uint32_t
- // infoCount - Number of shared libraries added Arg3: dyld_image_info
- // info[] - Array of structs of the form:
- // const struct mach_header
- // *imageLoadAddress
- // const char *imageFilePath
- // uintptr_t imageFileModDate (a time_t)
-
- DynamicLoaderMacOSXDYLD *dyld_instance = (DynamicLoaderMacOSXDYLD *)baton;
-
- // First step is to see if we've already initialized the all image infos. If
- // we haven't then this function will do so and return true. In the course
- // of initializing the all_image_infos it will read the complete current
- // state, so we don't need to figure out what has changed from the data
- // passed in to us.
-
- ExecutionContext exe_ctx(context->exe_ctx_ref);
- Process *process = exe_ctx.GetProcessPtr();
-
- // This is a sanity check just in case this dyld_instance is an old dyld
- // plugin's breakpoint still lying around.
- if (process != dyld_instance->m_process)
- return false;
-
- if (dyld_instance->InitializeFromAllImageInfos())
- return dyld_instance->GetStopWhenImagesChange();
-
- const lldb::ABISP &abi = process->GetABI();
- if (abi) {
- // Build up the value array to store the three arguments given above, then
- // get the values from the ABI:
-
- ClangASTContext *clang_ast_context =
- process->GetTarget().GetScratchClangASTContext();
- ValueList argument_values;
- Value input_value;
-
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- CompilerType clang_uint32_type =
- clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
- lldb::eEncodingUint, 32);
- input_value.SetValueType(Value::eValueTypeScalar);
- input_value.SetCompilerType(clang_uint32_type);
- // input_value.SetContext (Value::eContextTypeClangType,
- // clang_uint32_type);
- argument_values.PushValue(input_value);
- argument_values.PushValue(input_value);
- input_value.SetCompilerType(clang_void_ptr_type);
- // input_value.SetContext (Value::eContextTypeClangType,
- // clang_void_ptr_type);
- argument_values.PushValue(input_value);
-
- if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
- uint32_t dyld_mode =
- argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
- if (dyld_mode != static_cast<uint32_t>(-1)) {
- // Okay the mode was right, now get the number of elements, and the
- // array of new elements...
- uint32_t image_infos_count =
- argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
- if (image_infos_count != static_cast<uint32_t>(-1)) {
- // Got the number added, now go through the array of added elements,
- // putting out the mach header address, and adding the image. Note,
- // I'm not putting in logging here, since the AddModules &
- // RemoveModules functions do all the logging internally.
-
- lldb::addr_t image_infos_addr =
- argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
- if (dyld_mode == 0) {
- // This is add:
- dyld_instance->AddModulesUsingImageInfosAddress(image_infos_addr,
- image_infos_count);
- } else {
- // This is remove:
- dyld_instance->RemoveModulesUsingImageInfosAddress(
- image_infos_addr, image_infos_count);
- }
- }
- }
- }
- } else {
- process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
- "No ABI plugin located for triple %s -- shared libraries will not be "
- "registered!\n",
- process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
- }
-
- // Return true to stop the target, false to just let the target run
- return dyld_instance->GetStopWhenImagesChange();
-}
-
-bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // the all image infos is already valid for this process stop ID
- if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
- return true;
-
- m_dyld_all_image_infos.Clear();
- if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
- ByteOrder byte_order =
- m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint32_t addr_size =
- m_process->GetTarget().GetArchitecture().GetAddressByteSize();
-
- uint8_t buf[256];
- DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
- lldb::offset_t offset = 0;
-
- const size_t count_v2 = sizeof(uint32_t) + // version
- sizeof(uint32_t) + // infoArrayCount
- addr_size + // infoArray
- addr_size + // notification
- addr_size + // processDetachedFromSharedRegion +
- // libSystemInitialized + pad
- addr_size; // dyldImageLoadAddress
- const size_t count_v11 = count_v2 + addr_size + // jitInfo
- addr_size + // dyldVersion
- addr_size + // errorMessage
- addr_size + // terminationFlags
- addr_size + // coreSymbolicationShmPage
- addr_size + // systemOrderFlag
- addr_size + // uuidArrayCount
- addr_size + // uuidArray
- addr_size + // dyldAllImageInfosAddress
- addr_size + // initialImageCount
- addr_size + // errorKind
- addr_size + // errorClientOfDylibPath
- addr_size + // errorTargetDylibPath
- addr_size; // errorSymbol
- const size_t count_v13 = count_v11 + addr_size + // sharedCacheSlide
- sizeof(uuid_t); // sharedCacheUUID
- UNUSED_IF_ASSERT_DISABLED(count_v13);
- assert(sizeof(buf) >= count_v13);
-
- Status error;
- if (m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, 4, error) ==
- 4) {
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- // If anything in the high byte is set, we probably got the byte order
- // incorrect (the process might not have it set correctly yet due to
- // attaching to a program without a specified file).
- if (m_dyld_all_image_infos.version & 0xff000000) {
- // We have guessed the wrong byte order. Swap it and try reading the
- // version again.
- if (byte_order == eByteOrderLittle)
- byte_order = eByteOrderBig;
- else
- byte_order = eByteOrderLittle;
-
- data.SetByteOrder(byte_order);
- offset = 0;
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- }
- } else {
- return false;
- }
-
- const size_t count =
- (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
-
- const size_t bytes_read =
- m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, count, error);
- if (bytes_read == count) {
- offset = 0;
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
- m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
- m_dyld_all_image_infos.notification = data.GetPointer(&offset);
- m_dyld_all_image_infos.processDetachedFromSharedRegion =
- data.GetU8(&offset);
- m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
- // Adjust for padding.
- offset += addr_size - 2;
- m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
- if (m_dyld_all_image_infos.version >= 11) {
- offset += addr_size * 8;
- uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
-
- // When we started, we were given the actual address of the
- // all_image_infos struct (probably via TASK_DYLD_INFO) in memory -
- // this address is stored in m_dyld_all_image_infos_addr and is the
- // most accurate address we have.
-
- // We read the dyld_all_image_infos struct from memory; it contains its
- // own address. If the address in the struct does not match the actual
- // address, the dyld we're looking at has been loaded at a different
- // location (slid) from where it intended to load. The addresses in
- // the dyld_all_image_infos struct are the original, non-slid
- // addresses, and need to be adjusted. Most importantly the address of
- // dyld and the notification address need to be adjusted.
-
- if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) {
- uint64_t image_infos_offset =
- dyld_all_image_infos_addr -
- m_dyld_all_image_infos.dyldImageLoadAddress;
- uint64_t notification_offset =
- m_dyld_all_image_infos.notification -
- m_dyld_all_image_infos.dyldImageLoadAddress;
- m_dyld_all_image_infos.dyldImageLoadAddress =
- m_dyld_all_image_infos_addr - image_infos_offset;
- m_dyld_all_image_infos.notification =
- m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
- }
- }
- m_dyld_all_image_infos_stop_id = m_process->GetStopID();
- return true;
- }
- }
- return false;
-}
-
-bool DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress(
- lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
- ImageInfo::collection image_infos;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("Adding %d modules.\n", image_infos_count);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return true;
-
- StructuredData::ObjectSP image_infos_json_sp =
- m_process->GetLoadedDynamicLibrariesInfos(image_infos_addr,
- image_infos_count);
- if (image_infos_json_sp.get() && image_infos_json_sp->GetAsDictionary() &&
- image_infos_json_sp->GetAsDictionary()->HasKey("images") &&
- image_infos_json_sp->GetAsDictionary()
- ->GetValueForKey("images")
- ->GetAsArray() &&
- image_infos_json_sp->GetAsDictionary()
- ->GetValueForKey("images")
- ->GetAsArray()
- ->GetSize() == image_infos_count) {
- bool return_value = false;
- if (JSONImageInformationIntoImageInfo(image_infos_json_sp, image_infos)) {
- UpdateSpecialBinariesFromNewImageInfos(image_infos);
- return_value = AddModulesUsingImageInfos(image_infos);
- }
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- return return_value;
- }
-
- if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos))
- return false;
-
- UpdateImageInfosHeaderAndLoadCommands(image_infos, image_infos_count, false);
- bool return_value = AddModulesUsingImageInfos(image_infos);
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- return return_value;
-}
-
-bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress(
- lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
- ImageInfo::collection image_infos;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return true;
-
- // First read in the image_infos for the removed modules, and their headers &
- // load commands.
- if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) {
- if (log)
- log->PutCString("Failed reading image infos array.");
- return false;
- }
-
- if (log)
- log->Printf("Removing %d modules.", image_infos_count);
-
- ModuleList unloaded_module_list;
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
- if (log) {
- log->Printf("Removing module at address=0x%16.16" PRIx64 ".",
- image_infos[idx].address);
- image_infos[idx].PutToLog(log);
- }
-
- // Remove this image_infos from the m_all_image_infos. We do the
- // comparison by address rather than by file spec because we can have many
- // modules with the same "file spec" in the case that they are modules
- // loaded from memory.
- //
- // Also copy over the uuid from the old entry to the removed entry so we
- // can use it to lookup the module in the module list.
-
- ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
- for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
- if (image_infos[idx].address == (*pos).address) {
- image_infos[idx].uuid = (*pos).uuid;
-
- // Add the module from this image_info to the "unloaded_module_list".
- // We'll remove them all at one go later on.
-
- ModuleSP unload_image_module_sp(
- FindTargetModuleForImageInfo(image_infos[idx], false, NULL));
- if (unload_image_module_sp.get()) {
- // When we unload, be sure to use the image info from the old list,
- // since that has sections correctly filled in.
- UnloadModuleSections(unload_image_module_sp.get(), *pos);
- unloaded_module_list.AppendIfNeeded(unload_image_module_sp);
- } else {
- if (log) {
- log->Printf("Could not find module for unloading info entry:");
- image_infos[idx].PutToLog(log);
- }
- }
-
- // Then remove it from the m_dyld_image_infos:
-
- m_dyld_image_infos.erase(pos);
- break;
- }
- }
-
- if (pos == end) {
- if (log) {
- log->Printf("Could not find image_info entry for unloading image:");
- image_infos[idx].PutToLog(log);
- }
- }
- }
- if (unloaded_module_list.GetSize() > 0) {
- if (log) {
- log->PutCString("Unloaded:");
- unloaded_module_list.LogUUIDAndPaths(
- log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
- }
- m_process->GetTarget().GetImages().Remove(unloaded_module_list);
- }
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- return true;
-}
-
-bool DynamicLoaderMacOSXDYLD::ReadImageInfos(
- lldb::addr_t image_infos_addr, uint32_t image_infos_count,
- ImageInfo::collection &image_infos) {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- const ByteOrder endian = GetByteOrderFromMagic(m_dyld.header.magic);
- const uint32_t addr_size = m_dyld.GetAddressByteSize();
-
- image_infos.resize(image_infos_count);
- const size_t count = image_infos.size() * 3 * addr_size;
- DataBufferHeap info_data(count, 0);
- Status error;
- const size_t bytes_read = m_process->ReadMemory(
- image_infos_addr, info_data.GetBytes(), info_data.GetByteSize(), error);
- if (bytes_read == count) {
- lldb::offset_t info_data_offset = 0;
- DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(),
- endian, addr_size);
- for (size_t i = 0;
- i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset);
- i++) {
- image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
- lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
- image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
-
- char raw_path[PATH_MAX];
- m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path),
- error);
- // don't resolve the path
- if (error.Success()) {
- image_infos[i].file_spec.SetFile(raw_path, FileSpec::Style::native);
- }
- }
- return true;
- } else {
- return false;
- }
-}
-
-//----------------------------------------------------------------------
-// If we have found where the "_dyld_all_image_infos" lives in memory, read the
-// current info from it, and then update all image load addresses (or lack
-// thereof). Only do this if this is the first time we're reading the dyld
-// infos. Return true if we actually read anything, and false otherwise.
-//----------------------------------------------------------------------
-bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id ||
- m_dyld_image_infos.size() != 0)
- return false;
-
- if (ReadAllImageInfosStructure()) {
- // Nothing to load or unload?
- if (m_dyld_all_image_infos.dylib_info_count == 0)
- return true;
-
- if (m_dyld_all_image_infos.dylib_info_addr == 0) {
- // DYLD is updating the images now. So we should say we have no images,
- // and then we'll
- // figure it out when we hit the added breakpoint.
- return false;
- } else {
- if (!AddModulesUsingImageInfosAddress(
- m_dyld_all_image_infos.dylib_info_addr,
- m_dyld_all_image_infos.dylib_info_count)) {
- DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
- m_dyld_image_infos.clear();
- }
- }
-
- // Now we have one more bit of business. If there is a library left in the
- // images for our target that doesn't have a load address, then it must be
- // something that we were expecting to load (for instance we read a load
- // command for it) but it didn't in fact load - probably because
- // DYLD_*_PATH pointed to an equivalent version. We don't want it to stay
- // in the target's module list or it will confuse us, so unload it here.
- Target &target = m_process->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- ModuleList not_loaded_modules;
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
-
- size_t num_modules = target_modules.GetSize();
- for (size_t i = 0; i < num_modules; i++) {
- ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
- if (!module_sp->IsLoadedInTarget(&target)) {
- if (log) {
- StreamString s;
- module_sp->GetDescription(&s);
- log->Printf("Unloading pre-run module: %s.", s.GetData());
- }
- not_loaded_modules.Append(module_sp);
- }
- }
-
- if (not_loaded_modules.GetSize() != 0) {
- target.GetImages().Remove(not_loaded_modules);
- }
-
- return true;
- } else
- return false;
-}
-
-//----------------------------------------------------------------------
-// Read a mach_header at ADDR into HEADER, and also fill in the load command
-// data into LOAD_COMMAND_DATA if it is non-NULL.
-//
-// Returns true if we succeed, false if we fail for any reason.
-//----------------------------------------------------------------------
-bool DynamicLoaderMacOSXDYLD::ReadMachHeader(lldb::addr_t addr,
- llvm::MachO::mach_header *header,
- DataExtractor *load_command_data) {
- DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
- Status error;
- size_t bytes_read = m_process->ReadMemory(addr, header_bytes.GetBytes(),
- header_bytes.GetByteSize(), error);
- if (bytes_read == sizeof(llvm::MachO::mach_header)) {
- lldb::offset_t offset = 0;
- ::memset(header, 0, sizeof(llvm::MachO::mach_header));
-
- // Get the magic byte unswapped so we can figure out what we are dealing
- // with
- DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(),
- endian::InlHostByteOrder(), 4);
- header->magic = data.GetU32(&offset);
- lldb::addr_t load_cmd_addr = addr;
- data.SetByteOrder(
- DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
- switch (header->magic) {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_CIGAM:
- data.SetAddressByteSize(4);
- load_cmd_addr += sizeof(llvm::MachO::mach_header);
- break;
-
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM_64:
- data.SetAddressByteSize(8);
- load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
- break;
-
- default:
- return false;
- }
-
- // Read the rest of dyld's mach header
- if (data.GetU32(&offset, &header->cputype,
- (sizeof(llvm::MachO::mach_header) / sizeof(uint32_t)) -
- 1)) {
- if (load_command_data == NULL)
- return true; // We were able to read the mach_header and weren't asked
- // to read the load command bytes
-
- DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
-
- size_t load_cmd_bytes_read =
- m_process->ReadMemory(load_cmd_addr, load_cmd_data_sp->GetBytes(),
- load_cmd_data_sp->GetByteSize(), error);
-
- if (load_cmd_bytes_read == header->sizeofcmds) {
- // Set the load command data and also set the correct endian swap
- // settings and the correct address size
- load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
- load_command_data->SetByteOrder(data.GetByteOrder());
- load_command_data->SetAddressByteSize(data.GetAddressByteSize());
- return true; // We successfully read the mach_header and the load
- // command data
- }
-
- return false; // We weren't able to read the load command data
- }
- }
- return false; // We failed the read the mach_header
-}
-
-//----------------------------------------------------------------------
-// Parse the load commands for an image
-//----------------------------------------------------------------------
-uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
- ImageInfo &dylib_info,
- FileSpec *lc_id_dylinker) {
- lldb::offset_t offset = 0;
- uint32_t cmd_idx;
- Segment segment;
- dylib_info.Clear(true);
-
- for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) {
- // Clear out any load command specific data from DYLIB_INFO since we are
- // about to read it.
-
- if (data.ValidOffsetForDataOfSize(offset,
- sizeof(llvm::MachO::load_command))) {
- llvm::MachO::load_command load_cmd;
- lldb::offset_t load_cmd_offset = offset;
- load_cmd.cmd = data.GetU32(&offset);
- load_cmd.cmdsize = data.GetU32(&offset);
- switch (load_cmd.cmd) {
- case llvm::MachO::LC_SEGMENT: {
- segment.name.SetTrimmedCStringWithLength(
- (const char *)data.GetData(&offset, 16), 16);
- // We are putting 4 uint32_t values 4 uint64_t values so we have to use
- // multiple 32 bit gets below.
- segment.vmaddr = data.GetU32(&offset);
- segment.vmsize = data.GetU32(&offset);
- segment.fileoff = data.GetU32(&offset);
- segment.filesize = data.GetU32(&offset);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- dylib_info.segments.push_back(segment);
- } break;
-
- case llvm::MachO::LC_SEGMENT_64: {
- segment.name.SetTrimmedCStringWithLength(
- (const char *)data.GetData(&offset, 16), 16);
- // Extract vmaddr, vmsize, fileoff, and filesize all at once
- data.GetU64(&offset, &segment.vmaddr, 4);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- dylib_info.segments.push_back(segment);
- } break;
-
- case llvm::MachO::LC_ID_DYLINKER:
- if (lc_id_dylinker) {
- const lldb::offset_t name_offset =
- load_cmd_offset + data.GetU32(&offset);
- const char *path = data.PeekCStr(name_offset);
- lc_id_dylinker->SetFile(path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(*lc_id_dylinker);
- }
- break;
-
- case llvm::MachO::LC_UUID:
- dylib_info.uuid = UUID::fromOptionalData(data.GetData(&offset, 16), 16);
- break;
-
- default:
- break;
- }
- // Set offset to be the beginning of the next load command.
- offset = load_cmd_offset + load_cmd.cmdsize;
- }
- }
-
- // All sections listed in the dyld image info structure will all either be
- // fixed up already, or they will all be off by a single slide amount that is
- // determined by finding the first segment that is at file offset zero which
- // also has bytes (a file size that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = dylib_info.segments.size();
- for (size_t i = 0; i < num_sections; ++i) {
- // Iterate through the object file sections to find the first section that
- // starts of file offset zero and that has bytes in the file...
- if ((dylib_info.segments[i].fileoff == 0 &&
- dylib_info.segments[i].filesize > 0) ||
- (dylib_info.segments[i].name == ConstString("__TEXT"))) {
- dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
- // We have found the slide amount, so we can exit this for loop.
- break;
- }
- }
- return cmd_idx;
-}
-
-//----------------------------------------------------------------------
-// Read the mach_header and load commands for each image that the
-// _dyld_all_image_infos structure points to and cache the results.
-//----------------------------------------------------------------------
-
-void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(
- ImageInfo::collection &image_infos, uint32_t infos_count,
- bool update_executable) {
- uint32_t exe_idx = UINT32_MAX;
- // Read any UUID values that we can get
- for (uint32_t i = 0; i < infos_count; i++) {
- if (!image_infos[i].UUIDValid()) {
- DataExtractor data; // Load command data
- if (!ReadMachHeader(image_infos[i].address, &image_infos[i].header,
- &data))
- continue;
-
- ParseLoadCommands(data, image_infos[i], NULL);
-
- if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
- exe_idx = i;
- }
- }
-
- Target &target = m_process->GetTarget();
-
- if (exe_idx < image_infos.size()) {
- const bool can_create = true;
- ModuleSP exe_module_sp(
- FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL));
-
- if (exe_module_sp) {
- UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);
-
- if (exe_module_sp.get() != target.GetExecutableModulePointer()) {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded. Also when setting the
- // executable module, it will clear the targets module list, and if we
- // have an in memory dyld module, it will get removed from the list so
- // we will need to add it back after setting the executable module, so
- // we first try and see if we already have a weak pointer to the dyld
- // module, make it into a shared pointer, then add the executable, then
- // re-add it back to make sure it is always in the list.
- ModuleSP dyld_module_sp(GetDYLDModule());
-
- m_process->GetTarget().SetExecutableModule(exe_module_sp,
- eLoadDependentsNo);
-
- if (dyld_module_sp) {
- if (target.GetImages().AppendIfNeeded(dyld_module_sp)) {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
-
- // Also add it to the section list.
- UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
- }
- }
- }
- }
- }
-}
-
-//----------------------------------------------------------------------
-// Dump the _dyld_all_image_infos members and all current image infos that we
-// have parsed to the file handle provided.
-//----------------------------------------------------------------------
-void DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const {
- if (log == NULL)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- log->Printf(
- "dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64
- ", notify=0x%8.8" PRIx64 " }",
- m_dyld_all_image_infos.version, m_dyld_all_image_infos.dylib_info_count,
- (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
- (uint64_t)m_dyld_all_image_infos.notification);
- size_t i;
- const size_t count = m_dyld_image_infos.size();
- if (count > 0) {
- log->PutCString("Loaded:");
- for (i = 0; i < count; i++)
- m_dyld_image_infos[i].PutToLog(log);
- }
-}
-
-bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() {
- DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n",
- __FUNCTION__, StateAsCString(m_process->GetState()));
- if (m_break_id == LLDB_INVALID_BREAK_ID) {
- if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) {
- Address so_addr;
- // Set the notification breakpoint and install a breakpoint callback
- // function that will get called each time the breakpoint gets hit. We
- // will use this to track when shared libraries get loaded/unloaded.
- bool resolved = m_process->GetTarget().ResolveLoadAddress(
- m_dyld_all_image_infos.notification, so_addr);
- if (!resolved) {
- ModuleSP dyld_module_sp = GetDYLDModule();
- if (dyld_module_sp) {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
-
- UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
- resolved = m_process->GetTarget().ResolveLoadAddress(
- m_dyld_all_image_infos.notification, so_addr);
- }
- }
-
- if (resolved) {
- Breakpoint *dyld_break =
- m_process->GetTarget().CreateBreakpoint(so_addr, true, false).get();
- dyld_break->SetCallback(DynamicLoaderMacOSXDYLD::NotifyBreakpointHit,
- this, true);
- dyld_break->SetBreakpointKind("shared-library-event");
- m_break_id = dyld_break->GetID();
- }
- }
- }
- return m_break_id != LLDB_INVALID_BREAK_ID;
-}
-
-Status DynamicLoaderMacOSXDYLD::CanLoadImage() {
- Status error;
- // In order for us to tell if we can load a shared library we verify that the
- // dylib_info_addr isn't zero (which means no shared libraries have been set
- // yet, or dyld is currently mucking with the shared library list).
- if (ReadAllImageInfosStructure()) {
- // TODO: also check the _dyld_global_lock_held variable in
- // libSystem.B.dylib?
- // TODO: check the malloc lock?
- // TODO: check the objective C lock?
- if (m_dyld_all_image_infos.dylib_info_addr != 0)
- return error; // Success
- }
-
- error.SetErrorString("unsafe to load or unload shared libraries");
- return error;
-}
-
-bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
- lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
- LazyBool &private_shared_cache) {
- base_address = LLDB_INVALID_ADDRESS;
- uuid.Clear();
- using_shared_cache = eLazyBoolCalculate;
- private_shared_cache = eLazyBoolCalculate;
-
- if (m_process) {
- addr_t all_image_infos = m_process->GetImageInfoAddress();
-
- // The address returned by GetImageInfoAddress may be the address of dyld
- // (don't want) or it may be the address of the dyld_all_image_infos
- // structure (want). The first four bytes will be either the version field
- // (all_image_infos) or a Mach-O file magic constant. Version 13 and higher
- // of dyld_all_image_infos is required to get the sharedCacheUUID field.
-
- Status err;
- uint32_t version_or_magic =
- m_process->ReadUnsignedIntegerFromMemory(all_image_infos, 4, -1, err);
- if (version_or_magic != static_cast<uint32_t>(-1) &&
- version_or_magic != llvm::MachO::MH_MAGIC &&
- version_or_magic != llvm::MachO::MH_CIGAM &&
- version_or_magic != llvm::MachO::MH_MAGIC_64 &&
- version_or_magic != llvm::MachO::MH_CIGAM_64 &&
- version_or_magic >= 13) {
- addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
- int wordsize = m_process->GetAddressByteSize();
- if (wordsize == 8) {
- sharedCacheUUID_address =
- all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
- }
- if (wordsize == 4) {
- sharedCacheUUID_address =
- all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
- }
- if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS) {
- uuid_t shared_cache_uuid;
- if (m_process->ReadMemory(sharedCacheUUID_address, shared_cache_uuid,
- sizeof(uuid_t), err) == sizeof(uuid_t)) {
- uuid = UUID::fromOptionalData(shared_cache_uuid, 16);
- if (uuid.IsValid()) {
- using_shared_cache = eLazyBoolYes;
- }
- }
-
- if (version_or_magic >= 15) {
- // The sharedCacheBaseAddress field is the next one in the
- // dyld_all_image_infos struct.
- addr_t sharedCacheBaseAddr_address = sharedCacheUUID_address + 16;
- Status error;
- base_address = m_process->ReadUnsignedIntegerFromMemory(
- sharedCacheBaseAddr_address, wordsize, LLDB_INVALID_ADDRESS,
- error);
- if (error.Fail())
- base_address = LLDB_INVALID_ADDRESS;
- }
-
- return true;
- }
-
- //
- // add
- // NB: sharedCacheBaseAddress is the next field in dyld_all_image_infos
- // after
- // sharedCacheUUID -- that is, 16 bytes after it, if we wanted to fetch
- // it.
- }
- }
- return false;
-}
-
-void DynamicLoaderMacOSXDYLD::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
-}
-
-void DynamicLoaderMacOSXDYLD::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginNameStatic() {
- static ConstString g_name("macosx-dyld");
- return g_name;
-}
-
-const char *DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() {
- return "Dynamic loader plug-in that watches for shared library loads/unloads "
- "in MacOSX user processes.";
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t DynamicLoaderMacOSXDYLD::GetPluginVersion() { return 1; }
-
-uint32_t DynamicLoaderMacOSXDYLD::AddrByteSize() {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
-
- switch (m_dyld.header.magic) {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_CIGAM:
- return 4;
-
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM_64:
- return 8;
-
- default:
- break;
- }
- return 0;
-}
-
-lldb::ByteOrder DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic) {
- switch (magic) {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- return endian::InlHostByteOrder();
-
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- return lldb::eByteOrderLittle;
- else
- return lldb::eByteOrderBig;
-
- default:
- break;
- }
- return lldb::eByteOrderInvalid;
-}
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
deleted file mode 100644
index 3dc0f15bddf74..0000000000000
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- DynamicLoaderMacOSXDYLD.h -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
-// watchOS / BridgeOS)
-// platforms earlier than 2016, where lldb would read the "dyld_all_image_infos"
-// dyld internal structure to understand where things were loaded and the
-// solib loaded/unloaded notification function we put a breakpoint on gives us
-// an array of (load address, mod time, file path) tuples.
-//
-// As of late 2016, the new DynamicLoaderMacOS plugin should be used, which uses
-// dyld SPI functions to get the same information without reading internal dyld
-// data structures.
-
-#ifndef liblldb_DynamicLoaderMacOSXDYLD_h_
-#define liblldb_DynamicLoaderMacOSXDYLD_h_
-
-#include <mutex>
-#include <vector>
-
-#include "lldb/Host/SafeMachO.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/StructuredData.h"
-#include "lldb/Utility/UUID.h"
-
-#include "DynamicLoaderDarwin.h"
-
-class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin {
-public:
- DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
-
- virtual ~DynamicLoaderMacOSXDYLD() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::DynamicLoader *
- CreateInstance(lldb_private::Process *process, bool force);
-
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- bool ProcessDidExec() override;
-
- lldb_private::Status CanLoadImage() override;
-
- bool GetSharedCacheInformation(
- lldb::addr_t &base_address, lldb_private::UUID &uuid,
- lldb_private::LazyBool &using_shared_cache,
- lldb_private::LazyBool &private_shared_cache) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
-protected:
- void PutToLog(lldb_private::Log *log) const;
-
- void DoInitialImageFetch() override;
-
- bool NeedToDoInitialImageFetch() override;
-
- bool DidSetNotificationBreakpoint() override;
-
- void DoClear() override;
-
- bool ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr);
-
- static bool
- NotifyBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
- uint32_t AddrByteSize();
-
- bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header,
- lldb_private::DataExtractor *load_command_data);
-
- uint32_t ParseLoadCommands(const lldb_private::DataExtractor &data,
- ImageInfo &dylib_info,
- lldb_private::FileSpec *lc_id_dylinker);
-
- struct DYLDAllImageInfos {
- uint32_t version;
- uint32_t dylib_info_count; // Version >= 1
- lldb::addr_t dylib_info_addr; // Version >= 1
- lldb::addr_t notification; // Version >= 1
- bool processDetachedFromSharedRegion; // Version >= 1
- bool libSystemInitialized; // Version >= 2
- lldb::addr_t dyldImageLoadAddress; // Version >= 2
-
- DYLDAllImageInfos()
- : version(0), dylib_info_count(0),
- dylib_info_addr(LLDB_INVALID_ADDRESS),
- notification(LLDB_INVALID_ADDRESS),
- processDetachedFromSharedRegion(false), libSystemInitialized(false),
- dyldImageLoadAddress(LLDB_INVALID_ADDRESS) {}
-
- void Clear() {
- version = 0;
- dylib_info_count = 0;
- dylib_info_addr = LLDB_INVALID_ADDRESS;
- notification = LLDB_INVALID_ADDRESS;
- processDetachedFromSharedRegion = false;
- libSystemInitialized = false;
- dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
- }
-
- bool IsValid() const { return version >= 1 || version <= 6; }
- };
-
- static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
-
- bool SetNotificationBreakpoint() override;
-
- void ClearNotificationBreakpoint() override;
-
- // There is a little tricky bit where you might initially attach while dyld is
- // updating
- // the all_image_infos, and you can't read the infos, so you have to continue
- // and pick it
- // up when you hit the update breakpoint. At that point, you need to run this
- // initialize
- // function, but when you do it that way you DON'T need to do the extra work
- // you would at
- // the breakpoint.
- // So this function will only do actual work if the image infos haven't been
- // read yet.
- // If it does do any work, then it will return true, and false otherwise.
- // That way you can
- // call it in the breakpoint action, and if it returns true you're done.
- bool InitializeFromAllImageInfos();
-
- bool ReadAllImageInfosStructure();
-
- bool AddModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
- uint32_t image_infos_count);
-
- bool RemoveModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
- uint32_t image_infos_count);
-
- void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
-
- bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count,
- ImageInfo::collection &image_infos);
-
- lldb::addr_t m_dyld_all_image_infos_addr;
- DYLDAllImageInfos m_dyld_all_image_infos;
- uint32_t m_dyld_all_image_infos_stop_id;
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
- bool m_process_image_addr_is_all_images_infos;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOSXDYLD);
-};
-
-#endif // liblldb_DynamicLoaderMacOSXDYLD_h_
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt b/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
deleted file mode 100644
index 409ba92a0e19c..0000000000000
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-add_lldb_library(lldbPluginDynamicLoaderPosixDYLD PLUGIN
- AuxVector.cpp
- DYLDRendezvous.cpp
- DynamicLoaderPOSIXDYLD.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbPluginProcessElfCore
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/DynamicLoader/Static/CMakeLists.txt b/source/Plugins/DynamicLoader/Static/CMakeLists.txt
deleted file mode 100644
index be54a30534705..0000000000000
--- a/source/Plugins/DynamicLoader/Static/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginDynamicLoaderStatic PLUGIN
- DynamicLoaderStatic.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- )
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/CMakeLists.txt b/source/Plugins/DynamicLoader/Windows-DYLD/CMakeLists.txt
deleted file mode 100644
index 7557ada514662..0000000000000
--- a/source/Plugins/DynamicLoader/Windows-DYLD/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-add_lldb_library(lldbPluginDynamicLoaderWindowsDYLD PLUGIN
- DynamicLoaderWindowsDYLD.cpp
-
- LINK_LIBS
- lldbCore
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ExpressionParser/CMakeLists.txt b/source/Plugins/ExpressionParser/CMakeLists.txt
deleted file mode 100644
index 17c40aee44cc2..0000000000000
--- a/source/Plugins/ExpressionParser/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(Clang)
diff --git a/source/Plugins/ExpressionParser/Clang/CMakeLists.txt b/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
deleted file mode 100644
index ec4f6d5674e11..0000000000000
--- a/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-if(NOT LLDB_BUILT_STANDALONE)
- set(tablegen_deps intrinsics_gen)
-endif()
-
-add_lldb_library(lldbPluginExpressionParserClang PLUGIN
- ASTDumper.cpp
- ASTResultSynthesizer.cpp
- ASTStructExtractor.cpp
- ClangASTSource.cpp
- ClangExpressionDeclMap.cpp
- ClangExpressionParser.cpp
- ClangExpressionVariable.cpp
- ClangFunctionCaller.cpp
- ClangHost.cpp
- ClangModulesDeclVendor.cpp
- ClangPersistentVariables.cpp
- ClangUserExpression.cpp
- ClangUtilityFunction.cpp
- IRForTarget.cpp
-
- DEPENDS
- ${tablegen_deps}
-
- LINK_LIBS
- clangAST
- clangCodeGen
- clangDriver
- clangEdit
- clangFrontend
- clangLex
- clangParse
- clangRewrite
- clangRewriteFrontend
- clangSema
- clangSerialization
- lldbCore
- lldbExpression
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginCPlusPlusLanguage
- LINK_COMPONENTS
- Core
- ExecutionEngine
- ipo
- MCJIT
- Support
- )
diff --git a/source/Plugins/Instruction/ARM/CMakeLists.txt b/source/Plugins/Instruction/ARM/CMakeLists.txt
deleted file mode 100644
index 24f803db3d0e2..0000000000000
--- a/source/Plugins/Instruction/ARM/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-add_lldb_library(lldbPluginInstructionARM PLUGIN
- EmulateInstructionARM.cpp
- EmulationStateARM.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Instruction/ARM64/CMakeLists.txt b/source/Plugins/Instruction/ARM64/CMakeLists.txt
deleted file mode 100644
index effe0e3bfe660..0000000000000
--- a/source/Plugins/Instruction/ARM64/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginInstructionARM64 PLUGIN
- EmulateInstructionARM64.cpp
-
- LINK_LIBS
- lldbCore
- lldbInterpreter
- lldbSymbol
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Instruction/CMakeLists.txt b/source/Plugins/Instruction/CMakeLists.txt
deleted file mode 100644
index 89771e8f46d14..0000000000000
--- a/source/Plugins/Instruction/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-add_subdirectory(ARM)
-add_subdirectory(ARM64)
-add_subdirectory(MIPS)
-add_subdirectory(MIPS64)
-add_subdirectory(PPC64)
diff --git a/source/Plugins/Instruction/MIPS/CMakeLists.txt b/source/Plugins/Instruction/MIPS/CMakeLists.txt
deleted file mode 100644
index b2fe0ee8813f0..0000000000000
--- a/source/Plugins/Instruction/MIPS/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-if(Mips IN_LIST LLVM_TARGETS_TO_BUILD)
- set(mips_target Mips)
-endif()
-
-add_lldb_library(lldbPluginInstructionMIPS PLUGIN
- EmulateInstructionMIPS.cpp
-
- LINK_LIBS
- lldbCore
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbPluginProcessUtility
- LINK_COMPONENTS
- MC
- Support
- ${mips_target}
- )
diff --git a/source/Plugins/Instruction/MIPS64/CMakeLists.txt b/source/Plugins/Instruction/MIPS64/CMakeLists.txt
deleted file mode 100644
index ddb964bf50a59..0000000000000
--- a/source/Plugins/Instruction/MIPS64/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-if(Mips IN_LIST LLVM_TARGETS_TO_BUILD)
- set(mips_target Mips)
-endif()
-
-add_lldb_library(lldbPluginInstructionMIPS64 PLUGIN
- EmulateInstructionMIPS64.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbPluginProcessUtility
- LINK_COMPONENTS
- MC
- Support
- ${mips_target}
- )
diff --git a/source/Plugins/Instruction/PPC64/CMakeLists.txt b/source/Plugins/Instruction/PPC64/CMakeLists.txt
deleted file mode 100644
index 0926433fc77cf..0000000000000
--- a/source/Plugins/Instruction/PPC64/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginInstructionPPC64 PLUGIN
- EmulateInstructionPPC64.cpp
-
- LINK_LIBS
- lldbCore
- lldbInterpreter
- lldbSymbol
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt b/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt
deleted file mode 100644
index dc7464fd1939f..0000000000000
--- a/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginInstrumentationRuntimeASan PLUGIN
- ASanRuntime.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbExpression
- lldbInterpreter
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/InstrumentationRuntime/CMakeLists.txt b/source/Plugins/InstrumentationRuntime/CMakeLists.txt
deleted file mode 100644
index 55e8752e74242..0000000000000
--- a/source/Plugins/InstrumentationRuntime/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_subdirectory(ASan)
-add_subdirectory(MainThreadChecker)
-add_subdirectory(TSan)
-add_subdirectory(UBSan)
diff --git a/source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt b/source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt
deleted file mode 100644
index 440b176b27092..0000000000000
--- a/source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginInstrumentationRuntimeMainThreadChecker PLUGIN
- MainThreadCheckerRuntime.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbExpression
- lldbInterpreter
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt b/source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt
deleted file mode 100644
index 4dcd34131b8eb..0000000000000
--- a/source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-add_lldb_library(lldbPluginInstrumentationRuntimeTSan PLUGIN
- TSanRuntime.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbExpression
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt b/source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt
deleted file mode 100644
index 984bf86f83b5c..0000000000000
--- a/source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginInstrumentationRuntimeUBSan PLUGIN
- UBSanRuntime.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbExpression
- lldbInterpreter
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/JITLoader/CMakeLists.txt b/source/Plugins/JITLoader/CMakeLists.txt
deleted file mode 100644
index e52230199109f..0000000000000
--- a/source/Plugins/JITLoader/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(GDB)
diff --git a/source/Plugins/JITLoader/GDB/CMakeLists.txt b/source/Plugins/JITLoader/GDB/CMakeLists.txt
deleted file mode 100644
index 190599cbd588f..0000000000000
--- a/source/Plugins/JITLoader/GDB/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-add_lldb_library(lldbPluginJITLoaderGDB PLUGIN
- JITLoaderGDB.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- )
-
diff --git a/source/Plugins/Language/CMakeLists.txt b/source/Plugins/Language/CMakeLists.txt
deleted file mode 100644
index 7869074566d1e..0000000000000
--- a/source/Plugins/Language/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_subdirectory(ClangCommon)
-add_subdirectory(CPlusPlus)
-add_subdirectory(ObjC)
-add_subdirectory(ObjCPlusPlus)
diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
deleted file mode 100644
index bc357aa52b849..0000000000000
--- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
- BlockPointer.cpp
- CPlusPlusLanguage.cpp
- CPlusPlusNameParser.cpp
- CxxStringTypes.cpp
- LibCxx.cpp
- LibCxxAtomic.cpp
- LibCxxBitset.cpp
- LibCxxInitializerList.cpp
- LibCxxList.cpp
- LibCxxMap.cpp
- LibCxxOptional.cpp
- LibCxxQueue.cpp
- LibCxxTuple.cpp
- LibCxxUnorderedMap.cpp
- LibCxxVariant.cpp
- LibCxxVector.cpp
- LibStdcpp.cpp
- LibStdcppTuple.cpp
- LibStdcppUniquePointer.cpp
- MSVCUndecoratedNameParser.cpp
-
- LINK_LIBS
- lldbCore
- lldbDataFormatters
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginClangCommon
-
- LINK_COMPONENTS
- Support
-)
diff --git a/source/Plugins/Language/ClangCommon/CMakeLists.txt b/source/Plugins/Language/ClangCommon/CMakeLists.txt
deleted file mode 100644
index 854320dd312ec..0000000000000
--- a/source/Plugins/Language/ClangCommon/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-add_lldb_library(lldbPluginClangCommon PLUGIN
- ClangHighlighter.cpp
-
- LINK_LIBS
- lldbCore
- lldbUtility
- LINK_COMPONENTS
- Support
-)
diff --git a/source/Plugins/Language/ObjC/CMakeLists.txt b/source/Plugins/Language/ObjC/CMakeLists.txt
deleted file mode 100644
index afb68d4de8319..0000000000000
--- a/source/Plugins/Language/ObjC/CMakeLists.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-set(EXTRA_CXXFLAGS "")
-
-if (CXX_SUPPORTS_NO_GNU_ANONYMOUS_STRUCT)
- set(EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS} -Wno-gnu-anonymous-struct)
-endif ()
-
-if (CXX_SUPPORTS_NO_NESTED_ANON_TYPES)
- set(EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS} -Wno-nested-anon-types)
-endif ()
-
-add_lldb_library(lldbPluginObjCLanguage PLUGIN
- ObjCLanguage.cpp
- CF.cpp
- Cocoa.cpp
- CoreMedia.cpp
- NSArray.cpp
- NSDictionary.cpp
- NSError.cpp
- NSException.cpp
- NSIndexPath.cpp
- NSSet.cpp
- NSString.cpp
-
- LINK_LIBS
- clangAST
- lldbCore
- lldbDataFormatters
- lldbExpression
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginAppleObjCRuntime
- lldbPluginClangCommon
-
- EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS}
-)
diff --git a/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt b/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt
deleted file mode 100644
index 1aa5cc1ed4882..0000000000000
--- a/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_lldb_library(lldbPluginObjCPlusPlusLanguage PLUGIN
- ObjCPlusPlusLanguage.cpp
-
- LINK_LIBS
- lldbCore
- lldbTarget
- lldbPluginClangCommon
-)
diff --git a/source/Plugins/LanguageRuntime/CMakeLists.txt b/source/Plugins/LanguageRuntime/CMakeLists.txt
deleted file mode 100644
index c62791445a9a2..0000000000000
--- a/source/Plugins/LanguageRuntime/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_subdirectory(CPlusPlus)
-add_subdirectory(ObjC)
-add_subdirectory(RenderScript)
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt b/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
deleted file mode 100644
index 26c68c60b0198..0000000000000
--- a/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-add_subdirectory(ItaniumABI)
-#add_subdirectory(MicrosoftABI)
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt
deleted file mode 100644
index 14d1f46caebb9..0000000000000
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginCXXItaniumABI PLUGIN
- ItaniumABILanguageRuntime.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbInterpreter
- lldbSymbol
- lldbTarget
- )
diff --git a/source/Plugins/LanguageRuntime/Go/CMakeLists.txt b/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
deleted file mode 100644
index 62418def58f63..0000000000000
--- a/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-set(LLVM_NO_RTTI 1)
-
-add_lldb_library(lldbPluginLanguageRuntimeGo PLUGIN
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt
deleted file mode 100644
index 18f3ae1c5b1e3..0000000000000
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-add_lldb_library(lldbPluginAppleObjCRuntime PLUGIN
- AppleObjCRuntime.cpp
- AppleObjCRuntimeV1.cpp
- AppleObjCRuntimeV2.cpp
- AppleObjCTrampolineHandler.cpp
- AppleObjCDeclVendor.cpp
- AppleThreadPlanStepThroughObjCTrampoline.cpp
- AppleObjCClassDescriptorV2.cpp
- AppleObjCTypeEncodingParser.cpp
-
- LINK_LIBS
- clangAST
- lldbBreakpoint
- lldbCore
- lldbExpression
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginExpressionParserClang
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt b/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt
deleted file mode 100644
index af13dc6a144de..0000000000000
--- a/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(AppleObjCRuntime)
diff --git a/source/Plugins/LanguageRuntime/RenderScript/CMakeLists.txt b/source/Plugins/LanguageRuntime/RenderScript/CMakeLists.txt
deleted file mode 100644
index d944d76c49578..0000000000000
--- a/source/Plugins/LanguageRuntime/RenderScript/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(RenderScriptRuntime)
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt
deleted file mode 100644
index 1a6c499461340..0000000000000
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-if(NOT LLDB_BUILT_STANDALONE)
- set(tablegen_deps intrinsics_gen)
-endif()
-
-
-add_lldb_library(lldbPluginRenderScriptRuntime PLUGIN
- RenderScriptRuntime.cpp
- RenderScriptExpressionOpts.cpp
- RenderScriptx86ABIFixups.cpp
- RenderScriptScriptGroup.cpp
-
- DEPENDS
- ${tablegen_deps}
-
- LINK_LIBS
- clangBasic
- lldbBreakpoint
- lldbCore
- lldbDataFormatters
- lldbExpression
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Core
- IRReader
- Support
- Target
- )
diff --git a/source/Plugins/MemoryHistory/CMakeLists.txt b/source/Plugins/MemoryHistory/CMakeLists.txt
deleted file mode 100644
index 113f063625789..0000000000000
--- a/source/Plugins/MemoryHistory/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(asan)
diff --git a/source/Plugins/MemoryHistory/asan/CMakeLists.txt b/source/Plugins/MemoryHistory/asan/CMakeLists.txt
deleted file mode 100644
index 08deb75aabb11..0000000000000
--- a/source/Plugins/MemoryHistory/asan/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-add_lldb_library(lldbPluginMemoryHistoryASan PLUGIN
- MemoryHistoryASan.cpp
-
- LINK_LIBS
- lldbCore
- lldbExpression
- lldbTarget
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/CMakeLists.txt b/source/Plugins/ObjectContainer/BSD-Archive/CMakeLists.txt
deleted file mode 100644
index acc13d31ca257..0000000000000
--- a/source/Plugins/ObjectContainer/BSD-Archive/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginObjectContainerBSDArchive PLUGIN
- ObjectContainerBSDArchive.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ObjectContainer/CMakeLists.txt b/source/Plugins/ObjectContainer/CMakeLists.txt
deleted file mode 100644
index 5dcef91f07d21..0000000000000
--- a/source/Plugins/ObjectContainer/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-add_subdirectory(BSD-Archive)
-add_subdirectory(Universal-Mach-O)
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/CMakeLists.txt b/source/Plugins/ObjectContainer/Universal-Mach-O/CMakeLists.txt
deleted file mode 100644
index 9f173cf4c004a..0000000000000
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginObjectContainerMachOArchive PLUGIN
- ObjectContainerUniversalMachO.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- )
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
deleted file mode 100644
index 4c48d641829a4..0000000000000
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-//===-- ObjectContainerUniversalMachO.cpp -----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ObjectContainerUniversalMachO.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/Stream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace llvm::MachO;
-
-void ObjectContainerUniversalMachO::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance,
- GetModuleSpecifications);
-}
-
-void ObjectContainerUniversalMachO::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString ObjectContainerUniversalMachO::GetPluginNameStatic() {
- static ConstString g_name("mach-o");
- return g_name;
-}
-
-const char *ObjectContainerUniversalMachO::GetPluginDescriptionStatic() {
- return "Universal mach-o object container reader.";
-}
-
-ObjectContainer *ObjectContainerUniversalMachO::CreateInstance(
- const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
- lldb::offset_t data_offset, const FileSpec *file,
- lldb::offset_t file_offset, lldb::offset_t length) {
- // We get data when we aren't trying to look for cached container
- // information, so only try and look for an architecture slice if we get data
- if (data_sp) {
- DataExtractor data;
- data.SetData(data_sp, data_offset, length);
- if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
- std::unique_ptr<ObjectContainerUniversalMachO> container_ap(
- new ObjectContainerUniversalMachO(module_sp, data_sp, data_offset,
- file, file_offset, length));
- if (container_ap->ParseHeader()) {
- return container_ap.release();
- }
- }
- }
- return NULL;
-}
-
-bool ObjectContainerUniversalMachO::MagicBytesMatch(const DataExtractor &data) {
- lldb::offset_t offset = 0;
- uint32_t magic = data.GetU32(&offset);
- return magic == FAT_MAGIC || magic == FAT_CIGAM;
-}
-
-ObjectContainerUniversalMachO::ObjectContainerUniversalMachO(
- const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
- lldb::offset_t data_offset, const FileSpec *file,
- lldb::offset_t file_offset, lldb::offset_t length)
- : ObjectContainer(module_sp, file, file_offset, length, data_sp,
- data_offset),
- m_header(), m_fat_archs() {
- memset(&m_header, 0, sizeof(m_header));
-}
-
-ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO() {}
-
-bool ObjectContainerUniversalMachO::ParseHeader() {
- bool success = ParseHeader(m_data, m_header, m_fat_archs);
- // We no longer need any data, we parsed all we needed to parse and cached it
- // in m_header and m_fat_archs
- m_data.Clear();
- return success;
-}
-
-bool ObjectContainerUniversalMachO::ParseHeader(
- lldb_private::DataExtractor &data, llvm::MachO::fat_header &header,
- std::vector<llvm::MachO::fat_arch> &fat_archs) {
- bool success = false;
- // Store the file offset for this universal file as we could have a universal
- // .o file in a BSD archive, or be contained in another kind of object.
- // Universal mach-o files always have their headers in big endian.
- lldb::offset_t offset = 0;
- data.SetByteOrder(eByteOrderBig);
- header.magic = data.GetU32(&offset);
- fat_archs.clear();
-
- if (header.magic == FAT_MAGIC) {
-
- data.SetAddressByteSize(4);
-
- header.nfat_arch = data.GetU32(&offset);
-
- // Now we should have enough data for all of the fat headers, so lets index
- // them so we know how many architectures that this universal binary
- // contains.
- uint32_t arch_idx = 0;
- for (arch_idx = 0; arch_idx < header.nfat_arch; ++arch_idx) {
- if (data.ValidOffsetForDataOfSize(offset, sizeof(fat_arch))) {
- fat_arch arch;
- if (data.GetU32(&offset, &arch, sizeof(fat_arch) / sizeof(uint32_t)))
- fat_archs.push_back(arch);
- }
- }
- success = true;
- } else {
- memset(&header, 0, sizeof(header));
- }
- return success;
-}
-
-void ObjectContainerUniversalMachO::Dump(Stream *s) const {
- s->Printf("%p: ", static_cast<const void *>(this));
- s->Indent();
- const size_t num_archs = GetNumArchitectures();
- const size_t num_objects = GetNumObjects();
- s->Printf("ObjectContainerUniversalMachO, num_archs = %zu, num_objects = %zu",
- num_archs, num_objects);
- uint32_t i;
- ArchSpec arch;
- s->IndentMore();
- for (i = 0; i < num_archs; i++) {
- s->Indent();
- GetArchitectureAtIndex(i, arch);
- s->Printf("arch[%u] = %s\n", i, arch.GetArchitectureName());
- }
- for (i = 0; i < num_objects; i++) {
- s->Indent();
- s->Printf("object[%u] = %s\n", i, GetObjectNameAtIndex(i));
- }
- s->IndentLess();
- s->EOL();
-}
-
-size_t ObjectContainerUniversalMachO::GetNumArchitectures() const {
- return m_header.nfat_arch;
-}
-
-bool ObjectContainerUniversalMachO::GetArchitectureAtIndex(
- uint32_t idx, ArchSpec &arch) const {
- if (idx < m_header.nfat_arch) {
- arch.SetArchitecture(eArchTypeMachO, m_fat_archs[idx].cputype,
- m_fat_archs[idx].cpusubtype);
- return true;
- }
- return false;
-}
-
-ObjectFileSP
-ObjectContainerUniversalMachO::GetObjectFile(const FileSpec *file) {
- uint32_t arch_idx = 0;
- ArchSpec arch;
- // If the module hasn't specified an architecture yet, set it to the default
- // architecture:
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- if (!module_sp->GetArchitecture().IsValid()) {
- arch = Target::GetDefaultArchitecture();
- if (!arch.IsValid())
- arch.SetTriple(LLDB_ARCH_DEFAULT);
- } else
- arch = module_sp->GetArchitecture();
-
- ArchSpec curr_arch;
- // First, try to find an exact match for the Arch of the Target.
- for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
- if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
- arch.IsExactMatch(curr_arch))
- break;
- }
-
- // Failing an exact match, try to find a compatible Arch of the Target.
- if (arch_idx >= m_header.nfat_arch) {
- for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
- if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
- arch.IsCompatibleMatch(curr_arch))
- break;
- }
- }
-
- if (arch_idx < m_header.nfat_arch) {
- DataBufferSP data_sp;
- lldb::offset_t data_offset = 0;
- return ObjectFile::FindPlugin(
- module_sp, file, m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size, data_sp, data_offset);
- }
- }
- return ObjectFileSP();
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString ObjectContainerUniversalMachO::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ObjectContainerUniversalMachO::GetPluginVersion() { return 1; }
-
-size_t ObjectContainerUniversalMachO::GetModuleSpecifications(
- const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset, lldb::offset_t file_offset,
- lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
- const size_t initial_count = specs.GetSize();
-
- DataExtractor data;
- data.SetData(data_sp, data_offset, data_sp->GetByteSize());
-
- if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
- llvm::MachO::fat_header header;
- std::vector<llvm::MachO::fat_arch> fat_archs;
- if (ParseHeader(data, header, fat_archs)) {
- for (const llvm::MachO::fat_arch &fat_arch : fat_archs) {
- const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset;
- if (fat_arch.offset < file_size && file_size > slice_file_offset) {
- ObjectFile::GetModuleSpecifications(
- file, slice_file_offset, file_size - slice_file_offset, specs);
- }
- }
- }
- }
- return specs.GetSize() - initial_count;
-}
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
deleted file mode 100644
index d6e4fe1747cfb..0000000000000
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- ObjectContainerUniversalMachO.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_ObjectContainerUniversalMachO_h_
-#define liblldb_ObjectContainerUniversalMachO_h_
-
-#include "lldb/Host/SafeMachO.h"
-#include "lldb/Symbol/ObjectContainer.h"
-#include "lldb/Utility/FileSpec.h"
-
-class ObjectContainerUniversalMachO : public lldb_private::ObjectContainer {
-public:
- ObjectContainerUniversalMachO(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t offset, lldb::offset_t length);
-
- ~ObjectContainerUniversalMachO() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::ObjectContainer *
- CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset, const lldb_private::FileSpec *file,
- lldb::offset_t offset, lldb::offset_t length);
-
- static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
- lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool MagicBytesMatch(const lldb_private::DataExtractor &data);
-
- //------------------------------------------------------------------
- // Member Functions
- //------------------------------------------------------------------
- bool ParseHeader() override;
-
- void Dump(lldb_private::Stream *s) const override;
-
- size_t GetNumArchitectures() const override;
-
- bool GetArchitectureAtIndex(uint32_t cpu_idx,
- lldb_private::ArchSpec &arch) const override;
-
- lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
-protected:
- llvm::MachO::fat_header m_header;
- std::vector<llvm::MachO::fat_arch> m_fat_archs;
-
- static bool ParseHeader(lldb_private::DataExtractor &data,
- llvm::MachO::fat_header &header,
- std::vector<llvm::MachO::fat_arch> &fat_archs);
-};
-
-#endif // liblldb_ObjectContainerUniversalMachO_h_
diff --git a/source/Plugins/ObjectFile/Breakpad/CMakeLists.txt b/source/Plugins/ObjectFile/Breakpad/CMakeLists.txt
deleted file mode 100644
index 2f51b2c8719a7..0000000000000
--- a/source/Plugins/ObjectFile/Breakpad/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginObjectFileBreakpad PLUGIN
- ObjectFileBreakpad.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ObjectFile/CMakeLists.txt b/source/Plugins/ObjectFile/CMakeLists.txt
deleted file mode 100644
index 4edd667b9723d..0000000000000
--- a/source/Plugins/ObjectFile/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-add_subdirectory(Breakpad)
-add_subdirectory(ELF)
-add_subdirectory(Mach-O)
-add_subdirectory(PECOFF)
-add_subdirectory(JIT)
diff --git a/source/Plugins/ObjectFile/ELF/CMakeLists.txt b/source/Plugins/ObjectFile/ELF/CMakeLists.txt
deleted file mode 100644
index 45a4edcbb1c9e..0000000000000
--- a/source/Plugins/ObjectFile/ELF/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-add_lldb_library(lldbPluginObjectFileELF PLUGIN
- ELFHeader.cpp
- ObjectFileELF.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- BinaryFormat
- Object
- Support
- )
diff --git a/source/Plugins/ObjectFile/JIT/CMakeLists.txt b/source/Plugins/ObjectFile/JIT/CMakeLists.txt
deleted file mode 100644
index fd575532db4c7..0000000000000
--- a/source/Plugins/ObjectFile/JIT/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginObjectFileJIT PLUGIN
- ObjectFileJIT.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ObjectFile/Mach-O/CMakeLists.txt b/source/Plugins/ObjectFile/Mach-O/CMakeLists.txt
deleted file mode 100644
index d39b93768ae7d..0000000000000
--- a/source/Plugins/ObjectFile/Mach-O/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginObjectFileMachO PLUGIN
- ObjectFileMachO.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
deleted file mode 100644
index 06908fecf9841..0000000000000
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ /dev/null
@@ -1,6380 +0,0 @@
-//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/StringRef.h"
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
-#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RangeMap.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Core/StreamFile.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/DWARFCallFrameInfo.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/SectionLoadList.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadList.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-#include "lldb/Utility/UUID.h"
-
-#include "lldb/Host/SafeMachO.h"
-
-#include "llvm/Support/MemoryBuffer.h"
-
-#include "ObjectFileMachO.h"
-
-#if defined(__APPLE__) && \
- (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
-// GetLLDBSharedCacheUUID() needs to call dlsym()
-#include <dlfcn.h>
-#endif
-
-#ifndef __APPLE__
-#include "Utility/UuidCompatibility.h"
-#else
-#include <uuid/uuid.h>
-#endif
-
-#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
-using namespace lldb;
-using namespace lldb_private;
-using namespace llvm::MachO;
-
-// Some structure definitions needed for parsing the dyld shared cache files
-// found on iOS devices.
-
-struct lldb_copy_dyld_cache_header_v1 {
- char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
- uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
- uint32_t mappingCount; // number of dyld_cache_mapping_info entries
- uint32_t imagesOffset;
- uint32_t imagesCount;
- uint64_t dyldBaseAddress;
- uint64_t codeSignatureOffset;
- uint64_t codeSignatureSize;
- uint64_t slideInfoOffset;
- uint64_t slideInfoSize;
- uint64_t localSymbolsOffset;
- uint64_t localSymbolsSize;
- uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13
- // and later
-};
-
-struct lldb_copy_dyld_cache_mapping_info {
- uint64_t address;
- uint64_t size;
- uint64_t fileOffset;
- uint32_t maxProt;
- uint32_t initProt;
-};
-
-struct lldb_copy_dyld_cache_local_symbols_info {
- uint32_t nlistOffset;
- uint32_t nlistCount;
- uint32_t stringsOffset;
- uint32_t stringsSize;
- uint32_t entriesOffset;
- uint32_t entriesCount;
-};
-struct lldb_copy_dyld_cache_local_symbols_entry {
- uint32_t dylibOffset;
- uint32_t nlistStartIndex;
- uint32_t nlistCount;
-};
-
-class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {
-public:
- RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread,
- const DataExtractor &data)
- : RegisterContextDarwin_x86_64(thread, 0) {
- SetRegisterDataFrom_LC_THREAD(data);
- }
-
- void InvalidateAllRegisters() override {
- // Do nothing... registers are always valid...
- }
-
- void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
- lldb::offset_t offset = 0;
- SetError(GPRRegSet, Read, -1);
- SetError(FPURegSet, Read, -1);
- SetError(EXCRegSet, Read, -1);
- bool done = false;
-
- while (!done) {
- int flavor = data.GetU32(&offset);
- if (flavor == 0)
- done = true;
- else {
- uint32_t i;
- uint32_t count = data.GetU32(&offset);
- switch (flavor) {
- case GPRRegSet:
- for (i = 0; i < count; ++i)
- (&gpr.rax)[i] = data.GetU64(&offset);
- SetError(GPRRegSet, Read, 0);
- done = true;
-
- break;
- case FPURegSet:
- // TODO: fill in FPU regs....
- // SetError (FPURegSet, Read, -1);
- done = true;
-
- break;
- case EXCRegSet:
- exc.trapno = data.GetU32(&offset);
- exc.err = data.GetU32(&offset);
- exc.faultvaddr = data.GetU64(&offset);
- SetError(EXCRegSet, Read, 0);
- done = true;
- break;
- case 7:
- case 8:
- case 9:
- // fancy flavors that encapsulate of the above flavors...
- break;
-
- default:
- done = true;
- break;
- }
- }
- }
- }
-
- static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
- const char *alt_name, size_t reg_byte_size,
- Stream &data) {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info) {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
- ++i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
- }
- // Just write zeros if all else fails
- for (size_t i = 0; i < reg_byte_size; ++i)
- data.PutChar(0);
- return reg_byte_size;
- }
-
- static bool Create_LC_THREAD(Thread *thread, Stream &data) {
- RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
- if (reg_ctx_sp) {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32(GPRRegSet); // Flavor
- data.PutHex32(GPRWordCount);
- WriteRegister(reg_ctx, "rax", NULL, 8, data);
- WriteRegister(reg_ctx, "rbx", NULL, 8, data);
- WriteRegister(reg_ctx, "rcx", NULL, 8, data);
- WriteRegister(reg_ctx, "rdx", NULL, 8, data);
- WriteRegister(reg_ctx, "rdi", NULL, 8, data);
- WriteRegister(reg_ctx, "rsi", NULL, 8, data);
- WriteRegister(reg_ctx, "rbp", NULL, 8, data);
- WriteRegister(reg_ctx, "rsp", NULL, 8, data);
- WriteRegister(reg_ctx, "r8", NULL, 8, data);
- WriteRegister(reg_ctx, "r9", NULL, 8, data);
- WriteRegister(reg_ctx, "r10", NULL, 8, data);
- WriteRegister(reg_ctx, "r11", NULL, 8, data);
- WriteRegister(reg_ctx, "r12", NULL, 8, data);
- WriteRegister(reg_ctx, "r13", NULL, 8, data);
- WriteRegister(reg_ctx, "r14", NULL, 8, data);
- WriteRegister(reg_ctx, "r15", NULL, 8, data);
- WriteRegister(reg_ctx, "rip", NULL, 8, data);
- WriteRegister(reg_ctx, "rflags", NULL, 8, data);
- WriteRegister(reg_ctx, "cs", NULL, 8, data);
- WriteRegister(reg_ctx, "fs", NULL, 8, data);
- WriteRegister(reg_ctx, "gs", NULL, 8, data);
-
- // // Write out the FPU registers
- // const size_t fpu_byte_size = sizeof(FPU);
- // size_t bytes_written = 0;
- // data.PutHex32 (FPURegSet);
- // data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
- // bytes_written += data.PutHex32(0); // uint32_t pad[0]
- // bytes_written += data.PutHex32(0); // uint32_t pad[1]
- // bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2,
- // data); // uint16_t fcw; // "fctrl"
- // bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2,
- // data); // uint16_t fsw; // "fstat"
- // bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1,
- // data); // uint8_t ftw; // "ftag"
- // bytes_written += data.PutHex8 (0); // uint8_t pad1;
- // bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2,
- // data); // uint16_t fop; // "fop"
- // bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4,
- // data); // uint32_t ip; // "fioff"
- // bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2,
- // data); // uint16_t cs; // "fiseg"
- // bytes_written += data.PutHex16 (0); // uint16_t pad2;
- // bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4,
- // data); // uint32_t dp; // "fooff"
- // bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2,
- // data); // uint16_t ds; // "foseg"
- // bytes_written += data.PutHex16 (0); // uint16_t pad3;
- // bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4,
- // data); // uint32_t mxcsr;
- // bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL,
- // 4, data);// uint32_t mxcsrmask;
- // bytes_written += WriteRegister (reg_ctx, "stmm0", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "stmm1", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "stmm2", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "stmm3", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "stmm4", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "stmm5", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "stmm6", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "stmm7", NULL,
- // sizeof(MMSReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm10", NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm11", NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm12", NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm13", NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm14", NULL,
- // sizeof(XMMReg), data);
- // bytes_written += WriteRegister (reg_ctx, "xmm15", NULL,
- // sizeof(XMMReg), data);
- //
- // // Fill rest with zeros
- // for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++
- // i)
- // data.PutChar(0);
-
- // Write out the EXC registers
- data.PutHex32(EXCRegSet);
- data.PutHex32(EXCWordCount);
- WriteRegister(reg_ctx, "trapno", NULL, 4, data);
- WriteRegister(reg_ctx, "err", NULL, 4, data);
- WriteRegister(reg_ctx, "faultvaddr", NULL, 8, data);
- return true;
- }
- return false;
- }
-
-protected:
- int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
- return 0;
- }
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
- return 0;
- }
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
- return 0;
- }
-};
-
-class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386 {
-public:
- RegisterContextDarwin_i386_Mach(lldb_private::Thread &thread,
- const DataExtractor &data)
- : RegisterContextDarwin_i386(thread, 0) {
- SetRegisterDataFrom_LC_THREAD(data);
- }
-
- void InvalidateAllRegisters() override {
- // Do nothing... registers are always valid...
- }
-
- void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
- lldb::offset_t offset = 0;
- SetError(GPRRegSet, Read, -1);
- SetError(FPURegSet, Read, -1);
- SetError(EXCRegSet, Read, -1);
- bool done = false;
-
- while (!done) {
- int flavor = data.GetU32(&offset);
- if (flavor == 0)
- done = true;
- else {
- uint32_t i;
- uint32_t count = data.GetU32(&offset);
- switch (flavor) {
- case GPRRegSet:
- for (i = 0; i < count; ++i)
- (&gpr.eax)[i] = data.GetU32(&offset);
- SetError(GPRRegSet, Read, 0);
- done = true;
-
- break;
- case FPURegSet:
- // TODO: fill in FPU regs....
- // SetError (FPURegSet, Read, -1);
- done = true;
-
- break;
- case EXCRegSet:
- exc.trapno = data.GetU32(&offset);
- exc.err = data.GetU32(&offset);
- exc.faultvaddr = data.GetU32(&offset);
- SetError(EXCRegSet, Read, 0);
- done = true;
- break;
- case 7:
- case 8:
- case 9:
- // fancy flavors that encapsulate of the above flavors...
- break;
-
- default:
- done = true;
- break;
- }
- }
- }
- }
-
- static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
- const char *alt_name, size_t reg_byte_size,
- Stream &data) {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info) {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
- ++i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
- }
- // Just write zeros if all else fails
- for (size_t i = 0; i < reg_byte_size; ++i)
- data.PutChar(0);
- return reg_byte_size;
- }
-
- static bool Create_LC_THREAD(Thread *thread, Stream &data) {
- RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
- if (reg_ctx_sp) {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32(GPRRegSet); // Flavor
- data.PutHex32(GPRWordCount);
- WriteRegister(reg_ctx, "eax", NULL, 4, data);
- WriteRegister(reg_ctx, "ebx", NULL, 4, data);
- WriteRegister(reg_ctx, "ecx", NULL, 4, data);
- WriteRegister(reg_ctx, "edx", NULL, 4, data);
- WriteRegister(reg_ctx, "edi", NULL, 4, data);
- WriteRegister(reg_ctx, "esi", NULL, 4, data);
- WriteRegister(reg_ctx, "ebp", NULL, 4, data);
- WriteRegister(reg_ctx, "esp", NULL, 4, data);
- WriteRegister(reg_ctx, "ss", NULL, 4, data);
- WriteRegister(reg_ctx, "eflags", NULL, 4, data);
- WriteRegister(reg_ctx, "eip", NULL, 4, data);
- WriteRegister(reg_ctx, "cs", NULL, 4, data);
- WriteRegister(reg_ctx, "ds", NULL, 4, data);
- WriteRegister(reg_ctx, "es", NULL, 4, data);
- WriteRegister(reg_ctx, "fs", NULL, 4, data);
- WriteRegister(reg_ctx, "gs", NULL, 4, data);
-
- // Write out the EXC registers
- data.PutHex32(EXCRegSet);
- data.PutHex32(EXCWordCount);
- WriteRegister(reg_ctx, "trapno", NULL, 4, data);
- WriteRegister(reg_ctx, "err", NULL, 4, data);
- WriteRegister(reg_ctx, "faultvaddr", NULL, 4, data);
- return true;
- }
- return false;
- }
-
-protected:
- int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
- return 0;
- }
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
- return 0;
- }
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
- return 0;
- }
-};
-
-class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm {
-public:
- RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread,
- const DataExtractor &data)
- : RegisterContextDarwin_arm(thread, 0) {
- SetRegisterDataFrom_LC_THREAD(data);
- }
-
- void InvalidateAllRegisters() override {
- // Do nothing... registers are always valid...
- }
-
- void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
- lldb::offset_t offset = 0;
- SetError(GPRRegSet, Read, -1);
- SetError(FPURegSet, Read, -1);
- SetError(EXCRegSet, Read, -1);
- bool done = false;
-
- while (!done) {
- int flavor = data.GetU32(&offset);
- uint32_t count = data.GetU32(&offset);
- lldb::offset_t next_thread_state = offset + (count * 4);
- switch (flavor) {
- case GPRAltRegSet:
- case GPRRegSet:
- for (uint32_t i = 0; i < count; ++i) {
- gpr.r[i] = data.GetU32(&offset);
- }
-
- // Note that gpr.cpsr is also copied by the above loop; this loop
- // technically extends one element past the end of the gpr.r[] array.
-
- SetError(GPRRegSet, Read, 0);
- offset = next_thread_state;
- break;
-
- case FPURegSet: {
- uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats.s[0];
- const int fpu_reg_buf_size = sizeof(fpu.floats);
- if (data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
- fpu_reg_buf) == fpu_reg_buf_size) {
- offset += fpu_reg_buf_size;
- fpu.fpscr = data.GetU32(&offset);
- SetError(FPURegSet, Read, 0);
- } else {
- done = true;
- }
- }
- offset = next_thread_state;
- break;
-
- case EXCRegSet:
- if (count == 3) {
- exc.exception = data.GetU32(&offset);
- exc.fsr = data.GetU32(&offset);
- exc.far = data.GetU32(&offset);
- SetError(EXCRegSet, Read, 0);
- }
- done = true;
- offset = next_thread_state;
- break;
-
- // Unknown register set flavor, stop trying to parse.
- default:
- done = true;
- }
- }
- }
-
- static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
- const char *alt_name, size_t reg_byte_size,
- Stream &data) {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info) {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
- ++i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
- }
- // Just write zeros if all else fails
- for (size_t i = 0; i < reg_byte_size; ++i)
- data.PutChar(0);
- return reg_byte_size;
- }
-
- static bool Create_LC_THREAD(Thread *thread, Stream &data) {
- RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
- if (reg_ctx_sp) {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32(GPRRegSet); // Flavor
- data.PutHex32(GPRWordCount);
- WriteRegister(reg_ctx, "r0", NULL, 4, data);
- WriteRegister(reg_ctx, "r1", NULL, 4, data);
- WriteRegister(reg_ctx, "r2", NULL, 4, data);
- WriteRegister(reg_ctx, "r3", NULL, 4, data);
- WriteRegister(reg_ctx, "r4", NULL, 4, data);
- WriteRegister(reg_ctx, "r5", NULL, 4, data);
- WriteRegister(reg_ctx, "r6", NULL, 4, data);
- WriteRegister(reg_ctx, "r7", NULL, 4, data);
- WriteRegister(reg_ctx, "r8", NULL, 4, data);
- WriteRegister(reg_ctx, "r9", NULL, 4, data);
- WriteRegister(reg_ctx, "r10", NULL, 4, data);
- WriteRegister(reg_ctx, "r11", NULL, 4, data);
- WriteRegister(reg_ctx, "r12", NULL, 4, data);
- WriteRegister(reg_ctx, "sp", NULL, 4, data);
- WriteRegister(reg_ctx, "lr", NULL, 4, data);
- WriteRegister(reg_ctx, "pc", NULL, 4, data);
- WriteRegister(reg_ctx, "cpsr", NULL, 4, data);
-
- // Write out the EXC registers
- // data.PutHex32 (EXCRegSet);
- // data.PutHex32 (EXCWordCount);
- // WriteRegister (reg_ctx, "exception", NULL, 4, data);
- // WriteRegister (reg_ctx, "fsr", NULL, 4, data);
- // WriteRegister (reg_ctx, "far", NULL, 4, data);
- return true;
- }
- return false;
- }
-
-protected:
- int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
-
- int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
- return 0;
- }
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
- return 0;
- }
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
- return 0;
- }
-
- int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
- return -1;
- }
-};
-
-class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {
-public:
- RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread,
- const DataExtractor &data)
- : RegisterContextDarwin_arm64(thread, 0) {
- SetRegisterDataFrom_LC_THREAD(data);
- }
-
- void InvalidateAllRegisters() override {
- // Do nothing... registers are always valid...
- }
-
- void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
- lldb::offset_t offset = 0;
- SetError(GPRRegSet, Read, -1);
- SetError(FPURegSet, Read, -1);
- SetError(EXCRegSet, Read, -1);
- bool done = false;
- while (!done) {
- int flavor = data.GetU32(&offset);
- uint32_t count = data.GetU32(&offset);
- lldb::offset_t next_thread_state = offset + (count * 4);
- switch (flavor) {
- case GPRRegSet:
- // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1
- // 32-bit register)
- if (count >= (33 * 2) + 1) {
- for (uint32_t i = 0; i < 29; ++i)
- gpr.x[i] = data.GetU64(&offset);
- gpr.fp = data.GetU64(&offset);
- gpr.lr = data.GetU64(&offset);
- gpr.sp = data.GetU64(&offset);
- gpr.pc = data.GetU64(&offset);
- gpr.cpsr = data.GetU32(&offset);
- SetError(GPRRegSet, Read, 0);
- }
- offset = next_thread_state;
- break;
- case FPURegSet: {
- uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
- const int fpu_reg_buf_size = sizeof(fpu);
- if (fpu_reg_buf_size == count * sizeof(uint32_t) &&
- data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
- fpu_reg_buf) == fpu_reg_buf_size) {
- SetError(FPURegSet, Read, 0);
- } else {
- done = true;
- }
- }
- offset = next_thread_state;
- break;
- case EXCRegSet:
- if (count == 4) {
- exc.far = data.GetU64(&offset);
- exc.esr = data.GetU32(&offset);
- exc.exception = data.GetU32(&offset);
- SetError(EXCRegSet, Read, 0);
- }
- offset = next_thread_state;
- break;
- default:
- done = true;
- break;
- }
- }
- }
-
- static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
- const char *alt_name, size_t reg_byte_size,
- Stream &data) {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info) {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
- ++i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
- }
- // Just write zeros if all else fails
- for (size_t i = 0; i < reg_byte_size; ++i)
- data.PutChar(0);
- return reg_byte_size;
- }
-
- static bool Create_LC_THREAD(Thread *thread, Stream &data) {
- RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
- if (reg_ctx_sp) {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32(GPRRegSet); // Flavor
- data.PutHex32(GPRWordCount);
- WriteRegister(reg_ctx, "x0", NULL, 8, data);
- WriteRegister(reg_ctx, "x1", NULL, 8, data);
- WriteRegister(reg_ctx, "x2", NULL, 8, data);
- WriteRegister(reg_ctx, "x3", NULL, 8, data);
- WriteRegister(reg_ctx, "x4", NULL, 8, data);
- WriteRegister(reg_ctx, "x5", NULL, 8, data);
- WriteRegister(reg_ctx, "x6", NULL, 8, data);
- WriteRegister(reg_ctx, "x7", NULL, 8, data);
- WriteRegister(reg_ctx, "x8", NULL, 8, data);
- WriteRegister(reg_ctx, "x9", NULL, 8, data);
- WriteRegister(reg_ctx, "x10", NULL, 8, data);
- WriteRegister(reg_ctx, "x11", NULL, 8, data);
- WriteRegister(reg_ctx, "x12", NULL, 8, data);
- WriteRegister(reg_ctx, "x13", NULL, 8, data);
- WriteRegister(reg_ctx, "x14", NULL, 8, data);
- WriteRegister(reg_ctx, "x15", NULL, 8, data);
- WriteRegister(reg_ctx, "x16", NULL, 8, data);
- WriteRegister(reg_ctx, "x17", NULL, 8, data);
- WriteRegister(reg_ctx, "x18", NULL, 8, data);
- WriteRegister(reg_ctx, "x19", NULL, 8, data);
- WriteRegister(reg_ctx, "x20", NULL, 8, data);
- WriteRegister(reg_ctx, "x21", NULL, 8, data);
- WriteRegister(reg_ctx, "x22", NULL, 8, data);
- WriteRegister(reg_ctx, "x23", NULL, 8, data);
- WriteRegister(reg_ctx, "x24", NULL, 8, data);
- WriteRegister(reg_ctx, "x25", NULL, 8, data);
- WriteRegister(reg_ctx, "x26", NULL, 8, data);
- WriteRegister(reg_ctx, "x27", NULL, 8, data);
- WriteRegister(reg_ctx, "x28", NULL, 8, data);
- WriteRegister(reg_ctx, "fp", NULL, 8, data);
- WriteRegister(reg_ctx, "lr", NULL, 8, data);
- WriteRegister(reg_ctx, "sp", NULL, 8, data);
- WriteRegister(reg_ctx, "pc", NULL, 8, data);
- WriteRegister(reg_ctx, "cpsr", NULL, 4, data);
-
- // Write out the EXC registers
- // data.PutHex32 (EXCRegSet);
- // data.PutHex32 (EXCWordCount);
- // WriteRegister (reg_ctx, "far", NULL, 8, data);
- // WriteRegister (reg_ctx, "esr", NULL, 4, data);
- // WriteRegister (reg_ctx, "exception", NULL, 4, data);
- return true;
- }
- return false;
- }
-
-protected:
- int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
-
- int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
- return 0;
- }
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
- return 0;
- }
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
- return 0;
- }
-
- int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
- return -1;
- }
-};
-
-static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
- switch (magic) {
- case MH_MAGIC:
- case MH_CIGAM:
- return sizeof(struct mach_header);
-
- case MH_MAGIC_64:
- case MH_CIGAM_64:
- return sizeof(struct mach_header_64);
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
-
-void ObjectFileMachO::Initialize() {
- PluginManager::RegisterPlugin(
- GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
- CreateMemoryInstance, GetModuleSpecifications, SaveCore);
-}
-
-void ObjectFileMachO::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString ObjectFileMachO::GetPluginNameStatic() {
- static ConstString g_name("mach-o");
- return g_name;
-}
-
-const char *ObjectFileMachO::GetPluginDescriptionStatic() {
- return "Mach-o object file reader (32 and 64 bit)";
-}
-
-ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp,
- DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t length) {
- if (!data_sp) {
- data_sp = MapFileData(*file, length, file_offset);
- if (!data_sp)
- return nullptr;
- data_offset = 0;
- }
-
- if (!ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
- return nullptr;
-
- // Update the data to contain the entire file if it doesn't already
- if (data_sp->GetByteSize() < length) {
- data_sp = MapFileData(*file, length, file_offset);
- if (!data_sp)
- return nullptr;
- data_offset = 0;
- }
- auto objfile_ap = llvm::make_unique<ObjectFileMachO>(
- module_sp, data_sp, data_offset, file, file_offset, length);
- if (!objfile_ap || !objfile_ap->ParseHeader())
- return nullptr;
-
- return objfile_ap.release();
-}
-
-ObjectFile *ObjectFileMachO::CreateMemoryInstance(
- const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
- const ProcessSP &process_sp, lldb::addr_t header_addr) {
- if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
- std::unique_ptr<ObjectFile> objfile_ap(
- new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));
- if (objfile_ap.get() && objfile_ap->ParseHeader())
- return objfile_ap.release();
- }
- return NULL;
-}
-
-size_t ObjectFileMachO::GetModuleSpecifications(
- const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset, lldb::offset_t file_offset,
- lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
- const size_t initial_count = specs.GetSize();
-
- if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
- DataExtractor data;
- data.SetData(data_sp);
- llvm::MachO::mach_header header;
- if (ParseHeader(data, &data_offset, header)) {
- size_t header_and_load_cmds =
- header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
- if (header_and_load_cmds >= data_sp->GetByteSize()) {
- data_sp = MapFileData(file, header_and_load_cmds, file_offset);
- data.SetData(data_sp);
- data_offset = MachHeaderSizeFromMagic(header.magic);
- }
- if (data_sp) {
- ModuleSpec spec;
- spec.GetFileSpec() = file;
- spec.SetObjectOffset(file_offset);
- spec.SetObjectSize(length);
-
- spec.GetArchitecture() = GetArchitecture(header, data, data_offset);
- if (spec.GetArchitecture().IsValid()) {
- GetUUID(header, data, data_offset, spec.GetUUID());
- specs.Append(spec);
- }
- }
- }
- }
- return specs.GetSize() - initial_count;
-}
-
-const ConstString &ObjectFileMachO::GetSegmentNameTEXT() {
- static ConstString g_segment_name_TEXT("__TEXT");
- return g_segment_name_TEXT;
-}
-
-const ConstString &ObjectFileMachO::GetSegmentNameDATA() {
- static ConstString g_segment_name_DATA("__DATA");
- return g_segment_name_DATA;
-}
-
-const ConstString &ObjectFileMachO::GetSegmentNameDATA_DIRTY() {
- static ConstString g_segment_name("__DATA_DIRTY");
- return g_segment_name;
-}
-
-const ConstString &ObjectFileMachO::GetSegmentNameDATA_CONST() {
- static ConstString g_segment_name("__DATA_CONST");
- return g_segment_name;
-}
-
-const ConstString &ObjectFileMachO::GetSegmentNameOBJC() {
- static ConstString g_segment_name_OBJC("__OBJC");
- return g_segment_name_OBJC;
-}
-
-const ConstString &ObjectFileMachO::GetSegmentNameLINKEDIT() {
- static ConstString g_section_name_LINKEDIT("__LINKEDIT");
- return g_section_name_LINKEDIT;
-}
-
-const ConstString &ObjectFileMachO::GetSegmentNameDWARF() {
- static ConstString g_section_name("__DWARF");
- return g_section_name;
-}
-
-const ConstString &ObjectFileMachO::GetSectionNameEHFrame() {
- static ConstString g_section_name_eh_frame("__eh_frame");
- return g_section_name_eh_frame;
-}
-
-bool ObjectFileMachO::MagicBytesMatch(DataBufferSP &data_sp,
- lldb::addr_t data_offset,
- lldb::addr_t data_length) {
- DataExtractor data;
- data.SetData(data_sp, data_offset, data_length);
- lldb::offset_t offset = 0;
- uint32_t magic = data.GetU32(&offset);
- return MachHeaderSizeFromMagic(magic) != 0;
-}
-
-ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
- DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t length)
- : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_mach_segments(), m_mach_sections(), m_entry_point_address(),
- m_thread_context_offsets(), m_thread_context_offsets_valid(false),
- m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
- ::memset(&m_header, 0, sizeof(m_header));
- ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
-}
-
-ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP &header_data_sp,
- const lldb::ProcessSP &process_sp,
- lldb::addr_t header_addr)
- : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_mach_segments(), m_mach_sections(), m_entry_point_address(),
- m_thread_context_offsets(), m_thread_context_offsets_valid(false),
- m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
- ::memset(&m_header, 0, sizeof(m_header));
- ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
-}
-
-bool ObjectFileMachO::ParseHeader(DataExtractor &data,
- lldb::offset_t *data_offset_ptr,
- llvm::MachO::mach_header &header) {
- data.SetByteOrder(endian::InlHostByteOrder());
- // Leave magic in the original byte order
- header.magic = data.GetU32(data_offset_ptr);
- bool can_parse = false;
- bool is_64_bit = false;
- switch (header.magic) {
- case MH_MAGIC:
- data.SetByteOrder(endian::InlHostByteOrder());
- data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_MAGIC_64:
- data.SetByteOrder(endian::InlHostByteOrder());
- data.SetAddressByteSize(8);
- can_parse = true;
- is_64_bit = true;
- break;
-
- case MH_CIGAM:
- data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
- ? eByteOrderLittle
- : eByteOrderBig);
- data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_CIGAM_64:
- data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
- ? eByteOrderLittle
- : eByteOrderBig);
- data.SetAddressByteSize(8);
- is_64_bit = true;
- can_parse = true;
- break;
-
- default:
- break;
- }
-
- if (can_parse) {
- data.GetU32(data_offset_ptr, &header.cputype, 6);
- if (is_64_bit)
- *data_offset_ptr += 4;
- return true;
- } else {
- memset(&header, 0, sizeof(header));
- }
- return false;
-}
-
-bool ObjectFileMachO::ParseHeader() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- bool can_parse = false;
- lldb::offset_t offset = 0;
- m_data.SetByteOrder(endian::InlHostByteOrder());
- // Leave magic in the original byte order
- m_header.magic = m_data.GetU32(&offset);
- switch (m_header.magic) {
- case MH_MAGIC:
- m_data.SetByteOrder(endian::InlHostByteOrder());
- m_data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_MAGIC_64:
- m_data.SetByteOrder(endian::InlHostByteOrder());
- m_data.SetAddressByteSize(8);
- can_parse = true;
- break;
-
- case MH_CIGAM:
- m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
- ? eByteOrderLittle
- : eByteOrderBig);
- m_data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_CIGAM_64:
- m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
- ? eByteOrderLittle
- : eByteOrderBig);
- m_data.SetAddressByteSize(8);
- can_parse = true;
- break;
-
- default:
- break;
- }
-
- if (can_parse) {
- m_data.GetU32(&offset, &m_header.cputype, 6);
-
- if (ArchSpec mach_arch = GetArchitecture()) {
- // Check if the module has a required architecture
- const ArchSpec &module_arch = module_sp->GetArchitecture();
- if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
- return false;
-
- if (SetModulesArchitecture(mach_arch)) {
- const size_t header_and_lc_size =
- m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
- if (m_data.GetByteSize() < header_and_lc_size) {
- DataBufferSP data_sp;
- ProcessSP process_sp(m_process_wp.lock());
- if (process_sp) {
- data_sp =
- ReadMemory(process_sp, m_memory_addr, header_and_lc_size);
- } else {
- // Read in all only the load command data from the file on disk
- data_sp = MapFileData(m_file, header_and_lc_size, m_file_offset);
- if (data_sp->GetByteSize() != header_and_lc_size)
- return false;
- }
- if (data_sp)
- m_data.SetData(data_sp);
- }
- }
- return true;
- }
- } else {
- memset(&m_header, 0, sizeof(struct mach_header));
- }
- }
- return false;
-}
-
-ByteOrder ObjectFileMachO::GetByteOrder() const {
- return m_data.GetByteOrder();
-}
-
-bool ObjectFileMachO::IsExecutable() const {
- return m_header.filetype == MH_EXECUTE;
-}
-
-uint32_t ObjectFileMachO::GetAddressByteSize() const {
- return m_data.GetAddressByteSize();
-}
-
-AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
- Symtab *symtab = GetSymtab();
- if (symtab) {
- Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
- if (symbol) {
- if (symbol->ValueIsAddress()) {
- SectionSP section_sp(symbol->GetAddressRef().GetSection());
- if (section_sp) {
- const lldb::SectionType section_type = section_sp->GetType();
- switch (section_type) {
- case eSectionTypeInvalid:
- return AddressClass::eUnknown;
-
- case eSectionTypeCode:
- if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
- // For ARM we have a bit in the n_desc field of the symbol that
- // tells us ARM/Thumb which is bit 0x0008.
- if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
- return AddressClass::eCodeAlternateISA;
- }
- return AddressClass::eCode;
-
- case eSectionTypeContainer:
- return AddressClass::eUnknown;
-
- case eSectionTypeData:
- case eSectionTypeDataCString:
- case eSectionTypeDataCStringPointers:
- case eSectionTypeDataSymbolAddress:
- case eSectionTypeData4:
- case eSectionTypeData8:
- case eSectionTypeData16:
- case eSectionTypeDataPointers:
- case eSectionTypeZeroFill:
- case eSectionTypeDataObjCMessageRefs:
- case eSectionTypeDataObjCCFStrings:
- case eSectionTypeGoSymtab:
- return AddressClass::eData;
-
- case eSectionTypeDebug:
- case eSectionTypeDWARFDebugAbbrev:
- case eSectionTypeDWARFDebugAbbrevDwo:
- case eSectionTypeDWARFDebugAddr:
- case eSectionTypeDWARFDebugAranges:
- case eSectionTypeDWARFDebugCuIndex:
- case eSectionTypeDWARFDebugFrame:
- case eSectionTypeDWARFDebugInfo:
- case eSectionTypeDWARFDebugInfoDwo:
- case eSectionTypeDWARFDebugLine:
- case eSectionTypeDWARFDebugLineStr:
- case eSectionTypeDWARFDebugLoc:
- case eSectionTypeDWARFDebugLocLists:
- case eSectionTypeDWARFDebugMacInfo:
- case eSectionTypeDWARFDebugMacro:
- case eSectionTypeDWARFDebugNames:
- case eSectionTypeDWARFDebugPubNames:
- case eSectionTypeDWARFDebugPubTypes:
- case eSectionTypeDWARFDebugRanges:
- case eSectionTypeDWARFDebugRngLists:
- case eSectionTypeDWARFDebugStr:
- case eSectionTypeDWARFDebugStrDwo:
- case eSectionTypeDWARFDebugStrOffsets:
- case eSectionTypeDWARFDebugStrOffsetsDwo:
- case eSectionTypeDWARFDebugTypes:
- case eSectionTypeDWARFAppleNames:
- case eSectionTypeDWARFAppleTypes:
- case eSectionTypeDWARFAppleNamespaces:
- case eSectionTypeDWARFAppleObjC:
- case eSectionTypeDWARFGNUDebugAltLink:
- return AddressClass::eDebug;
-
- case eSectionTypeEHFrame:
- case eSectionTypeARMexidx:
- case eSectionTypeARMextab:
- case eSectionTypeCompactUnwind:
- return AddressClass::eRuntime;
-
- case eSectionTypeAbsoluteAddress:
- case eSectionTypeELFSymbolTable:
- case eSectionTypeELFDynamicSymbols:
- case eSectionTypeELFRelocationEntries:
- case eSectionTypeELFDynamicLinkInfo:
- case eSectionTypeOther:
- return AddressClass::eUnknown;
- }
- }
- }
-
- const SymbolType symbol_type = symbol->GetType();
- switch (symbol_type) {
- case eSymbolTypeAny:
- return AddressClass::eUnknown;
- case eSymbolTypeAbsolute:
- return AddressClass::eUnknown;
-
- case eSymbolTypeCode:
- case eSymbolTypeTrampoline:
- case eSymbolTypeResolver:
- if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
- // For ARM we have a bit in the n_desc field of the symbol that tells
- // us ARM/Thumb which is bit 0x0008.
- if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
- return AddressClass::eCodeAlternateISA;
- }
- return AddressClass::eCode;
-
- case eSymbolTypeData:
- return AddressClass::eData;
- case eSymbolTypeRuntime:
- return AddressClass::eRuntime;
- case eSymbolTypeException:
- return AddressClass::eRuntime;
- case eSymbolTypeSourceFile:
- return AddressClass::eDebug;
- case eSymbolTypeHeaderFile:
- return AddressClass::eDebug;
- case eSymbolTypeObjectFile:
- return AddressClass::eDebug;
- case eSymbolTypeCommonBlock:
- return AddressClass::eDebug;
- case eSymbolTypeBlock:
- return AddressClass::eDebug;
- case eSymbolTypeLocal:
- return AddressClass::eData;
- case eSymbolTypeParam:
- return AddressClass::eData;
- case eSymbolTypeVariable:
- return AddressClass::eData;
- case eSymbolTypeVariableType:
- return AddressClass::eDebug;
- case eSymbolTypeLineEntry:
- return AddressClass::eDebug;
- case eSymbolTypeLineHeader:
- return AddressClass::eDebug;
- case eSymbolTypeScopeBegin:
- return AddressClass::eDebug;
- case eSymbolTypeScopeEnd:
- return AddressClass::eDebug;
- case eSymbolTypeAdditional:
- return AddressClass::eUnknown;
- case eSymbolTypeCompiler:
- return AddressClass::eDebug;
- case eSymbolTypeInstrumentation:
- return AddressClass::eDebug;
- case eSymbolTypeUndefined:
- return AddressClass::eUnknown;
- case eSymbolTypeObjCClass:
- return AddressClass::eRuntime;
- case eSymbolTypeObjCMetaClass:
- return AddressClass::eRuntime;
- case eSymbolTypeObjCIVar:
- return AddressClass::eRuntime;
- case eSymbolTypeReExported:
- return AddressClass::eRuntime;
- }
- }
- }
- return AddressClass::eUnknown;
-}
-
-Symtab *ObjectFileMachO::GetSymtab() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_symtab_ap.get() == NULL) {
- m_symtab_ap.reset(new Symtab(this));
- std::lock_guard<std::recursive_mutex> symtab_guard(
- m_symtab_ap->GetMutex());
- ParseSymtab();
- m_symtab_ap->Finalize();
- }
- }
- return m_symtab_ap.get();
-}
-
-bool ObjectFileMachO::IsStripped() {
- if (m_dysymtab.cmd == 0) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
-
- load_command lc;
- if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
- break;
- if (lc.cmd == LC_DYSYMTAB) {
- m_dysymtab.cmd = lc.cmd;
- m_dysymtab.cmdsize = lc.cmdsize;
- if (m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
- (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) ==
- NULL) {
- // Clear m_dysymtab if we were unable to read all items from the
- // load command
- ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
- }
- }
- offset = load_cmd_offset + lc.cmdsize;
- }
- }
- }
- if (m_dysymtab.cmd)
- return m_dysymtab.nlocalsym <= 1;
- return false;
-}
-
-ObjectFileMachO::EncryptedFileRanges ObjectFileMachO::GetEncryptedFileRanges() {
- EncryptedFileRanges result;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
-
- encryption_info_command encryption_cmd;
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
- break;
-
- // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for the
- // 3 fields we care about, so treat them the same.
- if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
- encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
- if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
- if (encryption_cmd.cryptid != 0) {
- EncryptedFileRanges::Entry entry;
- entry.SetRangeBase(encryption_cmd.cryptoff);
- entry.SetByteSize(encryption_cmd.cryptsize);
- result.Append(entry);
- }
- }
- }
- offset = load_cmd_offset + encryption_cmd.cmdsize;
- }
-
- return result;
-}
-
-void ObjectFileMachO::SanitizeSegmentCommand(segment_command_64 &seg_cmd,
- uint32_t cmd_idx) {
- if (m_length == 0 || seg_cmd.filesize == 0)
- return;
-
- if (seg_cmd.fileoff > m_length) {
- // We have a load command that says it extends past the end of the file.
- // This is likely a corrupt file. We don't have any way to return an error
- // condition here (this method was likely invoked from something like
- // ObjectFile::GetSectionList()), so we just null out the section contents,
- // and dump a message to stdout. The most common case here is core file
- // debugging with a truncated file.
- const char *lc_segment_name =
- seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
- GetModule()->ReportWarning(
- "load command %u %s has a fileoff (0x%" PRIx64
- ") that extends beyond the end of the file (0x%" PRIx64
- "), ignoring this section",
- cmd_idx, lc_segment_name, seg_cmd.fileoff, m_length);
-
- seg_cmd.fileoff = 0;
- seg_cmd.filesize = 0;
- }
-
- if (seg_cmd.fileoff + seg_cmd.filesize > m_length) {
- // We have a load command that says it extends past the end of the file.
- // This is likely a corrupt file. We don't have any way to return an error
- // condition here (this method was likely invoked from something like
- // ObjectFile::GetSectionList()), so we just null out the section contents,
- // and dump a message to stdout. The most common case here is core file
- // debugging with a truncated file.
- const char *lc_segment_name =
- seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
- GetModule()->ReportWarning(
- "load command %u %s has a fileoff + filesize (0x%" PRIx64
- ") that extends beyond the end of the file (0x%" PRIx64
- "), the segment will be truncated to match",
- cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize, m_length);
-
- // Truncate the length
- seg_cmd.filesize = m_length - seg_cmd.fileoff;
- }
-}
-
-static uint32_t GetSegmentPermissions(const segment_command_64 &seg_cmd) {
- uint32_t result = 0;
- if (seg_cmd.initprot & VM_PROT_READ)
- result |= ePermissionsReadable;
- if (seg_cmd.initprot & VM_PROT_WRITE)
- result |= ePermissionsWritable;
- if (seg_cmd.initprot & VM_PROT_EXECUTE)
- result |= ePermissionsExecutable;
- return result;
-}
-
-static lldb::SectionType GetSectionType(uint32_t flags,
- ConstString section_name) {
-
- if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
- return eSectionTypeCode;
-
- uint32_t mach_sect_type = flags & SECTION_TYPE;
- static ConstString g_sect_name_objc_data("__objc_data");
- static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");
- static ConstString g_sect_name_objc_selrefs("__objc_selrefs");
- static ConstString g_sect_name_objc_classrefs("__objc_classrefs");
- static ConstString g_sect_name_objc_superrefs("__objc_superrefs");
- static ConstString g_sect_name_objc_const("__objc_const");
- static ConstString g_sect_name_objc_classlist("__objc_classlist");
- static ConstString g_sect_name_cfstring("__cfstring");
-
- static ConstString g_sect_name_dwarf_debug_abbrev("__debug_abbrev");
- static ConstString g_sect_name_dwarf_debug_aranges("__debug_aranges");
- static ConstString g_sect_name_dwarf_debug_frame("__debug_frame");
- static ConstString g_sect_name_dwarf_debug_info("__debug_info");
- static ConstString g_sect_name_dwarf_debug_line("__debug_line");
- static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
- static ConstString g_sect_name_dwarf_debug_loclists("__debug_loclists");
- static ConstString g_sect_name_dwarf_debug_macinfo("__debug_macinfo");
- static ConstString g_sect_name_dwarf_debug_names("__debug_names");
- static ConstString g_sect_name_dwarf_debug_pubnames("__debug_pubnames");
- static ConstString g_sect_name_dwarf_debug_pubtypes("__debug_pubtypes");
- static ConstString g_sect_name_dwarf_debug_ranges("__debug_ranges");
- static ConstString g_sect_name_dwarf_debug_str("__debug_str");
- static ConstString g_sect_name_dwarf_debug_types("__debug_types");
- static ConstString g_sect_name_dwarf_apple_names("__apple_names");
- static ConstString g_sect_name_dwarf_apple_types("__apple_types");
- static ConstString g_sect_name_dwarf_apple_namespaces("__apple_namespac");
- static ConstString g_sect_name_dwarf_apple_objc("__apple_objc");
- static ConstString g_sect_name_eh_frame("__eh_frame");
- static ConstString g_sect_name_compact_unwind("__unwind_info");
- static ConstString g_sect_name_text("__text");
- static ConstString g_sect_name_data("__data");
- static ConstString g_sect_name_go_symtab("__gosymtab");
-
- if (section_name == g_sect_name_dwarf_debug_abbrev)
- return eSectionTypeDWARFDebugAbbrev;
- if (section_name == g_sect_name_dwarf_debug_aranges)
- return eSectionTypeDWARFDebugAranges;
- if (section_name == g_sect_name_dwarf_debug_frame)
- return eSectionTypeDWARFDebugFrame;
- if (section_name == g_sect_name_dwarf_debug_info)
- return eSectionTypeDWARFDebugInfo;
- if (section_name == g_sect_name_dwarf_debug_line)
- return eSectionTypeDWARFDebugLine;
- if (section_name == g_sect_name_dwarf_debug_loc)
- return eSectionTypeDWARFDebugLoc;
- if (section_name == g_sect_name_dwarf_debug_loclists)
- return eSectionTypeDWARFDebugLocLists;
- if (section_name == g_sect_name_dwarf_debug_macinfo)
- return eSectionTypeDWARFDebugMacInfo;
- if (section_name == g_sect_name_dwarf_debug_names)
- return eSectionTypeDWARFDebugNames;
- if (section_name == g_sect_name_dwarf_debug_pubnames)
- return eSectionTypeDWARFDebugPubNames;
- if (section_name == g_sect_name_dwarf_debug_pubtypes)
- return eSectionTypeDWARFDebugPubTypes;
- if (section_name == g_sect_name_dwarf_debug_ranges)
- return eSectionTypeDWARFDebugRanges;
- if (section_name == g_sect_name_dwarf_debug_str)
- return eSectionTypeDWARFDebugStr;
- if (section_name == g_sect_name_dwarf_debug_types)
- return eSectionTypeDWARFDebugTypes;
- if (section_name == g_sect_name_dwarf_apple_names)
- return eSectionTypeDWARFAppleNames;
- if (section_name == g_sect_name_dwarf_apple_types)
- return eSectionTypeDWARFAppleTypes;
- if (section_name == g_sect_name_dwarf_apple_namespaces)
- return eSectionTypeDWARFAppleNamespaces;
- if (section_name == g_sect_name_dwarf_apple_objc)
- return eSectionTypeDWARFAppleObjC;
- if (section_name == g_sect_name_objc_selrefs)
- return eSectionTypeDataCStringPointers;
- if (section_name == g_sect_name_objc_msgrefs)
- return eSectionTypeDataObjCMessageRefs;
- if (section_name == g_sect_name_eh_frame)
- return eSectionTypeEHFrame;
- if (section_name == g_sect_name_compact_unwind)
- return eSectionTypeCompactUnwind;
- if (section_name == g_sect_name_cfstring)
- return eSectionTypeDataObjCCFStrings;
- if (section_name == g_sect_name_go_symtab)
- return eSectionTypeGoSymtab;
- if (section_name == g_sect_name_objc_data ||
- section_name == g_sect_name_objc_classrefs ||
- section_name == g_sect_name_objc_superrefs ||
- section_name == g_sect_name_objc_const ||
- section_name == g_sect_name_objc_classlist) {
- return eSectionTypeDataPointers;
- }
-
- switch (mach_sect_type) {
- // TODO: categorize sections by other flags for regular sections
- case S_REGULAR:
- if (section_name == g_sect_name_text)
- return eSectionTypeCode;
- if (section_name == g_sect_name_data)
- return eSectionTypeData;
- return eSectionTypeOther;
- case S_ZEROFILL:
- return eSectionTypeZeroFill;
- case S_CSTRING_LITERALS: // section with only literal C strings
- return eSectionTypeDataCString;
- case S_4BYTE_LITERALS: // section with only 4 byte literals
- return eSectionTypeData4;
- case S_8BYTE_LITERALS: // section with only 8 byte literals
- return eSectionTypeData8;
- case S_LITERAL_POINTERS: // section with only pointers to literals
- return eSectionTypeDataPointers;
- case S_NON_LAZY_SYMBOL_POINTERS: // section with only non-lazy symbol pointers
- return eSectionTypeDataPointers;
- case S_LAZY_SYMBOL_POINTERS: // section with only lazy symbol pointers
- return eSectionTypeDataPointers;
- case S_SYMBOL_STUBS: // section with only symbol stubs, byte size of stub in
- // the reserved2 field
- return eSectionTypeCode;
- case S_MOD_INIT_FUNC_POINTERS: // section with only function pointers for
- // initialization
- return eSectionTypeDataPointers;
- case S_MOD_TERM_FUNC_POINTERS: // section with only function pointers for
- // termination
- return eSectionTypeDataPointers;
- case S_COALESCED:
- return eSectionTypeOther;
- case S_GB_ZEROFILL:
- return eSectionTypeZeroFill;
- case S_INTERPOSING: // section with only pairs of function pointers for
- // interposing
- return eSectionTypeCode;
- case S_16BYTE_LITERALS: // section with only 16 byte literals
- return eSectionTypeData16;
- case S_DTRACE_DOF:
- return eSectionTypeDebug;
- case S_LAZY_DYLIB_SYMBOL_POINTERS:
- return eSectionTypeDataPointers;
- default:
- return eSectionTypeOther;
- }
-}
-
-struct ObjectFileMachO::SegmentParsingContext {
- const EncryptedFileRanges EncryptedRanges;
- lldb_private::SectionList &UnifiedList;
- uint32_t NextSegmentIdx = 0;
- uint32_t NextSectionIdx = 0;
- bool FileAddressesChanged = false;
-
- SegmentParsingContext(EncryptedFileRanges EncryptedRanges,
- lldb_private::SectionList &UnifiedList)
- : EncryptedRanges(std::move(EncryptedRanges)), UnifiedList(UnifiedList) {}
-};
-
-void ObjectFileMachO::ProcessSegmentCommand(const load_command &load_cmd_,
- lldb::offset_t offset,
- uint32_t cmd_idx,
- SegmentParsingContext &context) {
- segment_command_64 load_cmd;
- memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));
-
- if (!m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
- return;
-
- ModuleSP module_sp = GetModule();
- const bool is_core = GetType() == eTypeCoreFile;
- const bool is_dsym = (m_header.filetype == MH_DSYM);
- bool add_section = true;
- bool add_to_unified = true;
- ConstString const_segname(
- load_cmd.segname,
- std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
-
- SectionSP unified_section_sp(
- context.UnifiedList.FindSectionByName(const_segname));
- if (is_dsym && unified_section_sp) {
- if (const_segname == GetSegmentNameLINKEDIT()) {
- // We need to keep the __LINKEDIT segment private to this object file
- // only
- add_to_unified = false;
- } else {
- // This is the dSYM file and this section has already been created by the
- // object file, no need to create it.
- add_section = false;
- }
- }
- load_cmd.vmaddr = m_data.GetAddress(&offset);
- load_cmd.vmsize = m_data.GetAddress(&offset);
- load_cmd.fileoff = m_data.GetAddress(&offset);
- load_cmd.filesize = m_data.GetAddress(&offset);
- if (!m_data.GetU32(&offset, &load_cmd.maxprot, 4))
- return;
-
- SanitizeSegmentCommand(load_cmd, cmd_idx);
-
- const uint32_t segment_permissions = GetSegmentPermissions(load_cmd);
- const bool segment_is_encrypted =
- (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
-
- // Keep a list of mach segments around in case we need to get at data that
- // isn't stored in the abstracted Sections.
- m_mach_segments.push_back(load_cmd);
-
- // Use a segment ID of the segment index shifted left by 8 so they never
- // conflict with any of the sections.
- SectionSP segment_sp;
- if (add_section && (const_segname || is_core)) {
- segment_sp.reset(new Section(
- module_sp, // Module to which this section belongs
- this, // Object file to which this sections belongs
- ++context.NextSegmentIdx
- << 8, // Section ID is the 1 based segment index
- // shifted right by 8 bits as not to collide with any of the 256
- // section IDs that are possible
- const_segname, // Name of this section
- eSectionTypeContainer, // This section is a container of other
- // sections.
- load_cmd.vmaddr, // File VM address == addresses as they are
- // found in the object file
- load_cmd.vmsize, // VM size in bytes of this section
- load_cmd.fileoff, // Offset to the data for this section in
- // the file
- load_cmd.filesize, // Size in bytes of this section as found
- // in the file
- 0, // Segments have no alignment information
- load_cmd.flags)); // Flags for this section
-
- segment_sp->SetIsEncrypted(segment_is_encrypted);
- m_sections_ap->AddSection(segment_sp);
- segment_sp->SetPermissions(segment_permissions);
- if (add_to_unified)
- context.UnifiedList.AddSection(segment_sp);
- } else if (unified_section_sp) {
- if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
- // Check to see if the module was read from memory?
- if (module_sp->GetObjectFile()->GetBaseAddress().IsValid()) {
- // We have a module that is in memory and needs to have its file
- // address adjusted. We need to do this because when we load a file
- // from memory, its addresses will be slid already, yet the addresses
- // in the new symbol file will still be unslid. Since everything is
- // stored as section offset, this shouldn't cause any problems.
-
- // Make sure we've parsed the symbol table from the ObjectFile before
- // we go around changing its Sections.
- module_sp->GetObjectFile()->GetSymtab();
- // eh_frame would present the same problems but we parse that on a per-
- // function basis as-needed so it's more difficult to remove its use of
- // the Sections. Realistically, the environments where this code path
- // will be taken will not have eh_frame sections.
-
- unified_section_sp->SetFileAddress(load_cmd.vmaddr);
-
- // Notify the module that the section addresses have been changed once
- // we're done so any file-address caches can be updated.
- context.FileAddressesChanged = true;
- }
- }
- m_sections_ap->AddSection(unified_section_sp);
- }
-
- struct section_64 sect64;
- ::memset(&sect64, 0, sizeof(sect64));
- // Push a section into our mach sections for the section at index zero
- // (NO_SECT) if we don't have any mach sections yet...
- if (m_mach_sections.empty())
- m_mach_sections.push_back(sect64);
- uint32_t segment_sect_idx;
- const lldb::user_id_t first_segment_sectID = context.NextSectionIdx + 1;
-
- const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
- for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
- ++segment_sect_idx) {
- if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname,
- sizeof(sect64.sectname)) == NULL)
- break;
- if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,
- sizeof(sect64.segname)) == NULL)
- break;
- sect64.addr = m_data.GetAddress(&offset);
- sect64.size = m_data.GetAddress(&offset);
-
- if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
- break;
-
- // Keep a list of mach sections around in case we need to get at data that
- // isn't stored in the abstracted Sections.
- m_mach_sections.push_back(sect64);
-
- if (add_section) {
- ConstString section_name(
- sect64.sectname,
- std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
- if (!const_segname) {
- // We have a segment with no name so we need to conjure up segments
- // that correspond to the section's segname if there isn't already such
- // a section. If there is such a section, we resize the section so that
- // it spans all sections. We also mark these sections as fake so
- // address matches don't hit if they land in the gaps between the child
- // sections.
- const_segname.SetTrimmedCStringWithLength(sect64.segname,
- sizeof(sect64.segname));
- segment_sp = context.UnifiedList.FindSectionByName(const_segname);
- if (segment_sp.get()) {
- Section *segment = segment_sp.get();
- // Grow the section size as needed.
- const lldb::addr_t sect64_min_addr = sect64.addr;
- const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
- const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
- const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
- const lldb::addr_t curr_seg_max_addr =
- curr_seg_min_addr + curr_seg_byte_size;
- if (sect64_min_addr >= curr_seg_min_addr) {
- const lldb::addr_t new_seg_byte_size =
- sect64_max_addr - curr_seg_min_addr;
- // Only grow the section size if needed
- if (new_seg_byte_size > curr_seg_byte_size)
- segment->SetByteSize(new_seg_byte_size);
- } else {
- // We need to change the base address of the segment and adjust the
- // child section offsets for all existing children.
- const lldb::addr_t slide_amount =
- sect64_min_addr - curr_seg_min_addr;
- segment->Slide(slide_amount, false);
- segment->GetChildren().Slide(-slide_amount, false);
- segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);
- }
-
- // Grow the section size as needed.
- if (sect64.offset) {
- const lldb::addr_t segment_min_file_offset =
- segment->GetFileOffset();
- const lldb::addr_t segment_max_file_offset =
- segment_min_file_offset + segment->GetFileSize();
-
- const lldb::addr_t section_min_file_offset = sect64.offset;
- const lldb::addr_t section_max_file_offset =
- section_min_file_offset + sect64.size;
- const lldb::addr_t new_file_offset =
- std::min(section_min_file_offset, segment_min_file_offset);
- const lldb::addr_t new_file_size =
- std::max(section_max_file_offset, segment_max_file_offset) -
- new_file_offset;
- segment->SetFileOffset(new_file_offset);
- segment->SetFileSize(new_file_size);
- }
- } else {
- // Create a fake section for the section's named segment
- segment_sp.reset(new Section(
- segment_sp, // Parent section
- module_sp, // Module to which this section belongs
- this, // Object file to which this section belongs
- ++context.NextSegmentIdx
- << 8, // Section ID is the 1 based segment index
- // shifted right by 8 bits as not to
- // collide with any of the 256 section IDs
- // that are possible
- const_segname, // Name of this section
- eSectionTypeContainer, // This section is a container of
- // other sections.
- sect64.addr, // File VM address == addresses as they are
- // found in the object file
- sect64.size, // VM size in bytes of this section
- sect64.offset, // Offset to the data for this section in
- // the file
- sect64.offset ? sect64.size : 0, // Size in bytes of
- // this section as
- // found in the file
- sect64.align,
- load_cmd.flags)); // Flags for this section
- segment_sp->SetIsFake(true);
- segment_sp->SetPermissions(segment_permissions);
- m_sections_ap->AddSection(segment_sp);
- if (add_to_unified)
- context.UnifiedList.AddSection(segment_sp);
- segment_sp->SetIsEncrypted(segment_is_encrypted);
- }
- }
- assert(segment_sp.get());
-
- lldb::SectionType sect_type = GetSectionType(sect64.flags, section_name);
-
- SectionSP section_sp(new Section(
- segment_sp, module_sp, this, ++context.NextSectionIdx, section_name,
- sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
- sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
- sect64.flags));
- // Set the section to be encrypted to match the segment
-
- bool section_is_encrypted = false;
- if (!segment_is_encrypted && load_cmd.filesize != 0)
- section_is_encrypted = context.EncryptedRanges.FindEntryThatContains(
- sect64.offset) != NULL;
-
- section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
- section_sp->SetPermissions(segment_permissions);
- segment_sp->GetChildren().AddSection(section_sp);
-
- if (segment_sp->IsFake()) {
- segment_sp.reset();
- const_segname.Clear();
- }
- }
- }
- if (segment_sp && is_dsym) {
- if (first_segment_sectID <= context.NextSectionIdx) {
- lldb::user_id_t sect_uid;
- for (sect_uid = first_segment_sectID; sect_uid <= context.NextSectionIdx;
- ++sect_uid) {
- SectionSP curr_section_sp(
- segment_sp->GetChildren().FindSectionByID(sect_uid));
- SectionSP next_section_sp;
- if (sect_uid + 1 <= context.NextSectionIdx)
- next_section_sp =
- segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
-
- if (curr_section_sp.get()) {
- if (curr_section_sp->GetByteSize() == 0) {
- if (next_section_sp.get() != NULL)
- curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
- curr_section_sp->GetFileAddress());
- else
- curr_section_sp->SetByteSize(load_cmd.vmsize);
- }
- }
- }
- }
- }
-}
-
-void ObjectFileMachO::ProcessDysymtabCommand(const load_command &load_cmd,
- lldb::offset_t offset) {
- m_dysymtab.cmd = load_cmd.cmd;
- m_dysymtab.cmdsize = load_cmd.cmdsize;
- m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
- (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
-}
-
-void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
- if (m_sections_ap)
- return;
-
- m_sections_ap.reset(new SectionList());
-
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- // bool dump_sections = false;
- ModuleSP module_sp(GetModule());
-
- offset = MachHeaderSizeFromMagic(m_header.magic);
-
- SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);
- struct load_command load_cmd;
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
-
- if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
- ProcessSegmentCommand(load_cmd, offset, i, context);
- else if (load_cmd.cmd == LC_DYSYMTAB)
- ProcessDysymtabCommand(load_cmd, offset);
-
- offset = load_cmd_offset + load_cmd.cmdsize;
- }
-
- if (context.FileAddressesChanged && module_sp)
- module_sp->SectionFileAddressesChanged();
-}
-
-class MachSymtabSectionInfo {
-public:
- MachSymtabSectionInfo(SectionList *section_list)
- : m_section_list(section_list), m_section_infos() {
- // Get the number of sections down to a depth of 1 to include all segments
- // and their sections, but no other sections that may be added for debug
- // map or
- m_section_infos.resize(section_list->GetNumSections(1));
- }
-
- SectionSP GetSection(uint8_t n_sect, addr_t file_addr) {
- if (n_sect == 0)
- return SectionSP();
- if (n_sect < m_section_infos.size()) {
- if (!m_section_infos[n_sect].section_sp) {
- SectionSP section_sp(m_section_list->FindSectionByID(n_sect));
- m_section_infos[n_sect].section_sp = section_sp;
- if (section_sp) {
- m_section_infos[n_sect].vm_range.SetBaseAddress(
- section_sp->GetFileAddress());
- m_section_infos[n_sect].vm_range.SetByteSize(
- section_sp->GetByteSize());
- } else {
- Host::SystemLog(Host::eSystemLogError,
- "error: unable to find section for section %u\n",
- n_sect);
- }
- }
- if (m_section_infos[n_sect].vm_range.Contains(file_addr)) {
- // Symbol is in section.
- return m_section_infos[n_sect].section_sp;
- } else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 &&
- m_section_infos[n_sect].vm_range.GetBaseAddress() ==
- file_addr) {
- // Symbol is in section with zero size, but has the same start address
- // as the section. This can happen with linker symbols (symbols that
- // start with the letter 'l' or 'L'.
- return m_section_infos[n_sect].section_sp;
- }
- }
- return m_section_list->FindSectionContainingFileAddress(file_addr);
- }
-
-protected:
- struct SectionInfo {
- SectionInfo() : vm_range(), section_sp() {}
-
- VMRange vm_range;
- SectionSP section_sp;
- };
- SectionList *m_section_list;
- std::vector<SectionInfo> m_section_infos;
-};
-
-struct TrieEntry {
- TrieEntry()
- : name(), address(LLDB_INVALID_ADDRESS), flags(0), other(0),
- import_name() {}
-
- void Clear() {
- name.Clear();
- address = LLDB_INVALID_ADDRESS;
- flags = 0;
- other = 0;
- import_name.Clear();
- }
-
- void Dump() const {
- printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
- static_cast<unsigned long long>(address),
- static_cast<unsigned long long>(flags),
- static_cast<unsigned long long>(other), name.GetCString());
- if (import_name)
- printf(" -> \"%s\"\n", import_name.GetCString());
- else
- printf("\n");
- }
- ConstString name;
- uint64_t address;
- uint64_t flags;
- uint64_t other;
- ConstString import_name;
-};
-
-struct TrieEntryWithOffset {
- lldb::offset_t nodeOffset;
- TrieEntry entry;
-
- TrieEntryWithOffset(lldb::offset_t offset) : nodeOffset(offset), entry() {}
-
- void Dump(uint32_t idx) const {
- printf("[%3u] 0x%16.16llx: ", idx,
- static_cast<unsigned long long>(nodeOffset));
- entry.Dump();
- }
-
- bool operator<(const TrieEntryWithOffset &other) const {
- return (nodeOffset < other.nodeOffset);
- }
-};
-
-static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset,
- const bool is_arm,
- std::vector<llvm::StringRef> &nameSlices,
- std::set<lldb::addr_t> &resolver_addresses,
- std::vector<TrieEntryWithOffset> &output) {
- if (!data.ValidOffset(offset))
- return true;
-
- const uint64_t terminalSize = data.GetULEB128(&offset);
- lldb::offset_t children_offset = offset + terminalSize;
- if (terminalSize != 0) {
- TrieEntryWithOffset e(offset);
- e.entry.flags = data.GetULEB128(&offset);
- const char *import_name = NULL;
- if (e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
- e.entry.address = 0;
- e.entry.other = data.GetULEB128(&offset); // dylib ordinal
- import_name = data.GetCStr(&offset);
- } else {
- e.entry.address = data.GetULEB128(&offset);
- if (e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
- e.entry.other = data.GetULEB128(&offset);
- uint64_t resolver_addr = e.entry.other;
- if (is_arm)
- resolver_addr &= THUMB_ADDRESS_BIT_MASK;
- resolver_addresses.insert(resolver_addr);
- } else
- e.entry.other = 0;
- }
- // Only add symbols that are reexport symbols with a valid import name
- if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name &&
- import_name[0]) {
- std::string name;
- if (!nameSlices.empty()) {
- for (auto name_slice : nameSlices)
- name.append(name_slice.data(), name_slice.size());
- }
- if (name.size() > 1) {
- // Skip the leading '_'
- e.entry.name.SetCStringWithLength(name.c_str() + 1, name.size() - 1);
- }
- if (import_name) {
- // Skip the leading '_'
- e.entry.import_name.SetCString(import_name + 1);
- }
- output.push_back(e);
- }
- }
-
- const uint8_t childrenCount = data.GetU8(&children_offset);
- for (uint8_t i = 0; i < childrenCount; ++i) {
- const char *cstr = data.GetCStr(&children_offset);
- if (cstr)
- nameSlices.push_back(llvm::StringRef(cstr));
- else
- return false; // Corrupt data
- lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
- if (childNodeOffset) {
- if (!ParseTrieEntries(data, childNodeOffset, is_arm, nameSlices,
- resolver_addresses, output)) {
- return false;
- }
- }
- nameSlices.pop_back();
- }
- return true;
-}
-
-// Read the UUID out of a dyld_shared_cache file on-disk.
-UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache,
- const ByteOrder byte_order,
- const uint32_t addr_byte_size) {
- UUID dsc_uuid;
- DataBufferSP DscData = MapFileData(
- dyld_shared_cache, sizeof(struct lldb_copy_dyld_cache_header_v1), 0);
- if (!DscData)
- return dsc_uuid;
- DataExtractor dsc_header_data(DscData, byte_order, addr_byte_size);
-
- char version_str[7];
- lldb::offset_t offset = 0;
- memcpy(version_str, dsc_header_data.GetData(&offset, 6), 6);
- version_str[6] = '\0';
- if (strcmp(version_str, "dyld_v") == 0) {
- offset = offsetof(struct lldb_copy_dyld_cache_header_v1, uuid);
- dsc_uuid = UUID::fromOptionalData(
- dsc_header_data.GetData(&offset, sizeof(uuid_t)), sizeof(uuid_t));
- }
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
- if (log && dsc_uuid.IsValid()) {
- log->Printf("Shared cache %s has UUID %s", dyld_shared_cache.GetPath().c_str(),
- dsc_uuid.GetAsString().c_str());
- }
- return dsc_uuid;
-}
-
-size_t ObjectFileMachO::ParseSymtab() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "ObjectFileMachO::ParseSymtab () module = %s",
- m_file.GetFilename().AsCString(""));
- ModuleSP module_sp(GetModule());
- if (!module_sp)
- return 0;
-
- struct symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
- struct linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
- struct dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
- FunctionStarts function_starts;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t i;
- FileSpecList dylib_files;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
- static const llvm::StringRef g_objc_v2_prefix_class("_OBJC_CLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_metaclass("_OBJC_METACLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
-
- for (i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t cmd_offset = offset;
- // Read in the load command and load command size
- struct load_command lc;
- if (m_data.GetU32(&offset, &lc, 2) == NULL)
- break;
- // Watch for the symbol table load command
- switch (lc.cmd) {
- case LC_SYMTAB:
- symtab_load_command.cmd = lc.cmd;
- symtab_load_command.cmdsize = lc.cmdsize;
- // Read in the rest of the symtab load command
- if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) ==
- 0) // fill in symoff, nsyms, stroff, strsize fields
- return 0;
- if (symtab_load_command.symoff == 0) {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
- return 0;
- }
-
- if (symtab_load_command.stroff == 0) {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
- return 0;
- }
-
- if (symtab_load_command.nsyms == 0) {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
- return 0;
- }
-
- if (symtab_load_command.strsize == 0) {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
- return 0;
- }
- break;
-
- case LC_DYLD_INFO:
- case LC_DYLD_INFO_ONLY:
- if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) {
- dyld_info.cmd = lc.cmd;
- dyld_info.cmdsize = lc.cmdsize;
- } else {
- memset(&dyld_info, 0, sizeof(dyld_info));
- }
- break;
-
- case LC_LOAD_DYLIB:
- case LC_LOAD_WEAK_DYLIB:
- case LC_REEXPORT_DYLIB:
- case LC_LOADFVMLIB:
- case LC_LOAD_UPWARD_DYLIB: {
- uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
- const char *path = m_data.PeekCStr(name_offset);
- if (path) {
- FileSpec file_spec(path);
- // Strip the path if there is @rpath, @executable, etc so we just use
- // the basename
- if (path[0] == '@')
- file_spec.GetDirectory().Clear();
-
- if (lc.cmd == LC_REEXPORT_DYLIB) {
- m_reexported_dylibs.AppendIfUnique(file_spec);
- }
-
- dylib_files.Append(file_spec);
- }
- } break;
-
- case LC_FUNCTION_STARTS:
- function_starts_load_command.cmd = lc.cmd;
- function_starts_load_command.cmdsize = lc.cmdsize;
- if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
- NULL) // fill in symoff, nsyms, stroff, strsize fields
- memset(&function_starts_load_command, 0,
- sizeof(function_starts_load_command));
- break;
-
- default:
- break;
- }
- offset = cmd_offset + lc.cmdsize;
- }
-
- if (symtab_load_command.cmd) {
- Symtab *symtab = m_symtab_ap.get();
- SectionList *section_list = GetSectionList();
- if (section_list == NULL)
- return 0;
-
- const uint32_t addr_byte_size = m_data.GetAddressByteSize();
- const ByteOrder byte_order = m_data.GetByteOrder();
- bool bit_width_32 = addr_byte_size == 4;
- const size_t nlist_byte_size =
- bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
-
- DataExtractor nlist_data(NULL, 0, byte_order, addr_byte_size);
- DataExtractor strtab_data(NULL, 0, byte_order, addr_byte_size);
- DataExtractor function_starts_data(NULL, 0, byte_order, addr_byte_size);
- DataExtractor indirect_symbol_index_data(NULL, 0, byte_order,
- addr_byte_size);
- DataExtractor dyld_trie_data(NULL, 0, byte_order, addr_byte_size);
-
- const addr_t nlist_data_byte_size =
- symtab_load_command.nsyms * nlist_byte_size;
- const addr_t strtab_data_byte_size = symtab_load_command.strsize;
- addr_t strtab_addr = LLDB_INVALID_ADDRESS;
-
- ProcessSP process_sp(m_process_wp.lock());
- Process *process = process_sp.get();
-
- uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
-
- if (process && m_header.filetype != llvm::MachO::MH_OBJECT) {
- Target &target = process->GetTarget();
-
- memory_module_load_level = target.GetMemoryModuleLoadLevel();
-
- SectionSP linkedit_section_sp(
- section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
- // Reading mach file from memory in a process or core file...
-
- if (linkedit_section_sp) {
- addr_t linkedit_load_addr =
- linkedit_section_sp->GetLoadBaseAddress(&target);
- if (linkedit_load_addr == LLDB_INVALID_ADDRESS) {
- // We might be trying to access the symbol table before the
- // __LINKEDIT's load address has been set in the target. We can't
- // fail to read the symbol table, so calculate the right address
- // manually
- linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
- m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
- }
-
- const addr_t linkedit_file_offset =
- linkedit_section_sp->GetFileOffset();
- const addr_t symoff_addr = linkedit_load_addr +
- symtab_load_command.symoff -
- linkedit_file_offset;
- strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
- linkedit_file_offset;
-
- bool data_was_read = false;
-
-#if defined(__APPLE__) && \
- (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
- if (m_header.flags & 0x80000000u &&
- process->GetAddressByteSize() == sizeof(void *)) {
- // This mach-o memory file is in the dyld shared cache. If this
- // program is not remote and this is iOS, then this process will
- // share the same shared cache as the process we are debugging and we
- // can read the entire __LINKEDIT from the address space in this
- // process. This is a needed optimization that is used for local iOS
- // debugging only since all shared libraries in the shared cache do
- // not have corresponding files that exist in the file system of the
- // device. They have been combined into a single file. This means we
- // always have to load these files from memory. All of the symbol and
- // string tables from all of the __LINKEDIT sections from the shared
- // libraries in the shared cache have been merged into a single large
- // symbol and string table. Reading all of this symbol and string
- // table data across can slow down debug launch times, so we optimize
- // this by reading the memory for the __LINKEDIT section from this
- // process.
-
- UUID lldb_shared_cache;
- addr_t lldb_shared_cache_addr;
- GetLLDBSharedCacheUUID (lldb_shared_cache_addr, lldb_shared_cache);
- UUID process_shared_cache;
- addr_t process_shared_cache_addr;
- GetProcessSharedCacheUUID(process, process_shared_cache_addr, process_shared_cache);
- bool use_lldb_cache = true;
- if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() &&
- (lldb_shared_cache != process_shared_cache
- || process_shared_cache_addr != lldb_shared_cache_addr)) {
- use_lldb_cache = false;
- }
-
- PlatformSP platform_sp(target.GetPlatform());
- if (platform_sp && platform_sp->IsHost() && use_lldb_cache) {
- data_was_read = true;
- nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size,
- eByteOrderLittle);
- strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size,
- eByteOrderLittle);
- if (function_starts_load_command.cmd) {
- const addr_t func_start_addr =
- linkedit_load_addr + function_starts_load_command.dataoff -
- linkedit_file_offset;
- function_starts_data.SetData(
- (void *)func_start_addr,
- function_starts_load_command.datasize, eByteOrderLittle);
- }
- }
- }
-#endif
-
- if (!data_was_read) {
- // Always load dyld - the dynamic linker - from memory if we didn't
- // find a binary anywhere else. lldb will not register
- // dylib/framework/bundle loads/unloads if we don't have the dyld
- // symbols, we force dyld to load from memory despite the user's
- // target.memory-module-load-level setting.
- if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
- m_header.filetype == llvm::MachO::MH_DYLINKER) {
- DataBufferSP nlist_data_sp(
- ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
- if (nlist_data_sp)
- nlist_data.SetData(nlist_data_sp, 0,
- nlist_data_sp->GetByteSize());
- if (m_dysymtab.nindirectsyms != 0) {
- const addr_t indirect_syms_addr = linkedit_load_addr +
- m_dysymtab.indirectsymoff -
- linkedit_file_offset;
- DataBufferSP indirect_syms_data_sp(
- ReadMemory(process_sp, indirect_syms_addr,
- m_dysymtab.nindirectsyms * 4));
- if (indirect_syms_data_sp)
- indirect_symbol_index_data.SetData(
- indirect_syms_data_sp, 0,
- indirect_syms_data_sp->GetByteSize());
- // If this binary is outside the shared cache,
- // cache the string table.
- // Binaries in the shared cache all share a giant string table, and
- // we can't share the string tables across multiple ObjectFileMachO's,
- // so we'd end up re-reading this mega-strtab for every binary
- // in the shared cache - it would be a big perf problem.
- // For binaries outside the shared cache, it's faster to read the
- // entire strtab at once instead of piece-by-piece as we process
- // the nlist records.
- if ((m_header.flags & 0x80000000u) == 0) {
- DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr,
- strtab_data_byte_size));
- if (strtab_data_sp) {
- strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
- }
- }
- }
- }
- if (memory_module_load_level >=
- eMemoryModuleLoadLevelPartial) {
- if (function_starts_load_command.cmd) {
- const addr_t func_start_addr =
- linkedit_load_addr + function_starts_load_command.dataoff -
- linkedit_file_offset;
- DataBufferSP func_start_data_sp(
- ReadMemory(process_sp, func_start_addr,
- function_starts_load_command.datasize));
- if (func_start_data_sp)
- function_starts_data.SetData(func_start_data_sp, 0,
- func_start_data_sp->GetByteSize());
- }
- }
- }
- }
- } else {
- nlist_data.SetData(m_data, symtab_load_command.symoff,
- nlist_data_byte_size);
- strtab_data.SetData(m_data, symtab_load_command.stroff,
- strtab_data_byte_size);
-
- if (dyld_info.export_size > 0) {
- dyld_trie_data.SetData(m_data, dyld_info.export_off,
- dyld_info.export_size);
- }
-
- if (m_dysymtab.nindirectsyms != 0) {
- indirect_symbol_index_data.SetData(m_data, m_dysymtab.indirectsymoff,
- m_dysymtab.nindirectsyms * 4);
- }
- if (function_starts_load_command.cmd) {
- function_starts_data.SetData(m_data,
- function_starts_load_command.dataoff,
- function_starts_load_command.datasize);
- }
- }
-
- if (nlist_data.GetByteSize() == 0 &&
- memory_module_load_level == eMemoryModuleLoadLevelComplete) {
- if (log)
- module_sp->LogMessage(log, "failed to read nlist data");
- return 0;
- }
-
- const bool have_strtab_data = strtab_data.GetByteSize() > 0;
- if (!have_strtab_data) {
- if (process) {
- if (strtab_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- module_sp->LogMessage(log, "failed to locate the strtab in memory");
- return 0;
- }
- } else {
- if (log)
- module_sp->LogMessage(log, "failed to read strtab data");
- return 0;
- }
- }
-
- const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
- const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
- const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
- const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
- const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
- const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
- SectionSP text_section_sp(
- section_list->FindSectionByName(g_segment_name_TEXT));
- SectionSP data_section_sp(
- section_list->FindSectionByName(g_segment_name_DATA));
- SectionSP data_dirty_section_sp(
- section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
- SectionSP data_const_section_sp(
- section_list->FindSectionByName(g_segment_name_DATA_CONST));
- SectionSP objc_section_sp(
- section_list->FindSectionByName(g_segment_name_OBJC));
- SectionSP eh_frame_section_sp;
- if (text_section_sp.get())
- eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
- g_section_name_eh_frame);
- else
- eh_frame_section_sp =
- section_list->FindSectionByName(g_section_name_eh_frame);
-
- const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
-
- // lldb works best if it knows the start address of all functions in a
- // module. Linker symbols or debug info are normally the best source of
- // information for start addr / size but they may be stripped in a released
- // binary. Two additional sources of information exist in Mach-O binaries:
- // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each
- // function's start address in the
- // binary, relative to the text section.
- // eh_frame - the eh_frame FDEs have the start addr & size of
- // each function
- // LC_FUNCTION_STARTS is the fastest source to read in, and is present on
- // all modern binaries.
- // Binaries built to run on older releases may need to use eh_frame
- // information.
-
- if (text_section_sp && function_starts_data.GetByteSize()) {
- FunctionStarts::Entry function_start_entry;
- function_start_entry.data = false;
- lldb::offset_t function_start_offset = 0;
- function_start_entry.addr = text_section_sp->GetFileAddress();
- uint64_t delta;
- while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
- 0) {
- // Now append the current entry
- function_start_entry.addr += delta;
- function_starts.Append(function_start_entry);
- }
- } else {
- // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the
- // load command claiming an eh_frame but it doesn't actually have the
- // eh_frame content. And if we have a dSYM, we don't need to do any of
- // this fill-in-the-missing-symbols works anyway - the debug info should
- // give us all the functions in the module.
- if (text_section_sp.get() && eh_frame_section_sp.get() &&
- m_type != eTypeDebugInfo) {
- DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,
- DWARFCallFrameInfo::EH);
- DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
- eh_frame.GetFunctionAddressAndSizeVector(functions);
- addr_t text_base_addr = text_section_sp->GetFileAddress();
- size_t count = functions.GetSize();
- for (size_t i = 0; i < count; ++i) {
- const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func =
- functions.GetEntryAtIndex(i);
- if (func) {
- FunctionStarts::Entry function_start_entry;
- function_start_entry.addr = func->base - text_base_addr;
- function_starts.Append(function_start_entry);
- }
- }
- }
- }
-
- const size_t function_starts_count = function_starts.GetSize();
-
- // For user process binaries (executables, dylibs, frameworks, bundles), if
- // we don't have LC_FUNCTION_STARTS/eh_frame section in this binary, we're
- // going to assume the binary has been stripped. Don't allow assembly
- // language instruction emulation because we don't know proper function
- // start boundaries.
- //
- // For all other types of binaries (kernels, stand-alone bare board
- // binaries, kexts), they may not have LC_FUNCTION_STARTS / eh_frame
- // sections - we should not make any assumptions about them based on that.
- if (function_starts_count == 0 && CalculateStrata() == eStrataUser) {
- m_allow_assembly_emulation_unwind_plans = false;
- Log *unwind_or_symbol_log(lldb_private::GetLogIfAnyCategoriesSet(
- LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND));
-
- if (unwind_or_symbol_log)
- module_sp->LogMessage(
- unwind_or_symbol_log,
- "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
- }
-
- const user_id_t TEXT_eh_frame_sectID =
- eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
- : static_cast<user_id_t>(NO_SECT);
-
- lldb::offset_t nlist_data_offset = 0;
-
- uint32_t N_SO_index = UINT32_MAX;
-
- MachSymtabSectionInfo section_info(section_list);
- std::vector<uint32_t> N_FUN_indexes;
- std::vector<uint32_t> N_NSYM_indexes;
- std::vector<uint32_t> N_INCL_indexes;
- std::vector<uint32_t> N_BRAC_indexes;
- std::vector<uint32_t> N_COMM_indexes;
- typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
- typedef std::map<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
- typedef std::map<const char *, uint32_t> ConstNameToSymbolIndexMap;
- ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
- ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
- ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
- // Any symbols that get merged into another will get an entry in this map
- // so we know
- NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
- uint32_t nlist_idx = 0;
- Symbol *symbol_ptr = NULL;
-
- uint32_t sym_idx = 0;
- Symbol *sym = NULL;
- size_t num_syms = 0;
- std::string memory_symbol_name;
- uint32_t unmapped_local_symbols_found = 0;
-
- std::vector<TrieEntryWithOffset> trie_entries;
- std::set<lldb::addr_t> resolver_addresses;
-
- if (dyld_trie_data.GetByteSize() > 0) {
- std::vector<llvm::StringRef> nameSlices;
- ParseTrieEntries(dyld_trie_data, 0, is_arm, nameSlices,
- resolver_addresses, trie_entries);
-
- ConstString text_segment_name("__TEXT");
- SectionSP text_segment_sp =
- GetSectionList()->FindSectionByName(text_segment_name);
- if (text_segment_sp) {
- const lldb::addr_t text_segment_file_addr =
- text_segment_sp->GetFileAddress();
- if (text_segment_file_addr != LLDB_INVALID_ADDRESS) {
- for (auto &e : trie_entries)
- e.entry.address += text_segment_file_addr;
- }
- }
- }
-
- typedef std::set<ConstString> IndirectSymbols;
- IndirectSymbols indirect_symbol_names;
-
-#if defined(__APPLE__) && \
- (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
-
- // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
- // optimized by moving LOCAL symbols out of the memory mapped portion of
- // the DSC. The symbol information has all been retained, but it isn't
- // available in the normal nlist data. However, there *are* duplicate
- // entries of *some*
- // LOCAL symbols in the normal nlist data. To handle this situation
- // correctly, we must first attempt
- // to parse any DSC unmapped symbol information. If we find any, we set a
- // flag that tells the normal nlist parser to ignore all LOCAL symbols.
-
- if (m_header.flags & 0x80000000u) {
- // Before we can start mapping the DSC, we need to make certain the
- // target process is actually using the cache we can find.
-
- // Next we need to determine the correct path for the dyld shared cache.
-
- ArchSpec header_arch;
- GetArchitecture(header_arch);
- char dsc_path[PATH_MAX];
- char dsc_path_development[PATH_MAX];
-
- snprintf(
- dsc_path, sizeof(dsc_path), "%s%s%s",
- "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
- */
- "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
- header_arch.GetArchitectureName());
-
- snprintf(
- dsc_path_development, sizeof(dsc_path), "%s%s%s%s",
- "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
- */
- "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
- header_arch.GetArchitectureName(), ".development");
-
- FileSpec dsc_nondevelopment_filespec(dsc_path, false);
- FileSpec dsc_development_filespec(dsc_path_development, false);
- FileSpec dsc_filespec;
-
- UUID dsc_uuid;
- UUID process_shared_cache_uuid;
- addr_t process_shared_cache_base_addr;
-
- if (process) {
- GetProcessSharedCacheUUID(process, process_shared_cache_base_addr, process_shared_cache_uuid);
- }
-
- // First see if we can find an exact match for the inferior process
- // shared cache UUID in the development or non-development shared caches
- // on disk.
- if (process_shared_cache_uuid.IsValid()) {
- if (FileSystem::Instance().Exists(dsc_development_filespec)) {
- UUID dsc_development_uuid = GetSharedCacheUUID(
- dsc_development_filespec, byte_order, addr_byte_size);
- if (dsc_development_uuid.IsValid() &&
- dsc_development_uuid == process_shared_cache_uuid) {
- dsc_filespec = dsc_development_filespec;
- dsc_uuid = dsc_development_uuid;
- }
- }
- if (!dsc_uuid.IsValid() &&
- FileSystem::Instance().Exists(dsc_nondevelopment_filespec)) {
- UUID dsc_nondevelopment_uuid = GetSharedCacheUUID(
- dsc_nondevelopment_filespec, byte_order, addr_byte_size);
- if (dsc_nondevelopment_uuid.IsValid() &&
- dsc_nondevelopment_uuid == process_shared_cache_uuid) {
- dsc_filespec = dsc_nondevelopment_filespec;
- dsc_uuid = dsc_nondevelopment_uuid;
- }
- }
- }
-
- // Failing a UUID match, prefer the development dyld_shared cache if both
- // are present.
- if (!FileSystem::Instance().Exists(dsc_filespec)) {
- if (FileSystem::Instance().Exists(dsc_development_filespec)) {
- dsc_filespec = dsc_development_filespec;
- } else {
- dsc_filespec = dsc_nondevelopment_filespec;
- }
- }
-
- /* The dyld_cache_header has a pointer to the
- dyld_cache_local_symbols_info structure (localSymbolsOffset).
- The dyld_cache_local_symbols_info structure gives us three things:
- 1. The start and count of the nlist records in the dyld_shared_cache
- file
- 2. The start and size of the strings for these nlist records
- 3. The start and count of dyld_cache_local_symbols_entry entries
-
- There is one dyld_cache_local_symbols_entry per dylib/framework in the
- dyld shared cache.
- The "dylibOffset" field is the Mach-O header of this dylib/framework in
- the dyld shared cache.
- The dyld_cache_local_symbols_entry also lists the start of this
- dylib/framework's nlist records
- and the count of how many nlist records there are for this
- dylib/framework.
- */
-
- // Process the dyld shared cache header to find the unmapped symbols
-
- DataBufferSP dsc_data_sp = MapFileData(
- dsc_filespec, sizeof(struct lldb_copy_dyld_cache_header_v1), 0);
- if (!dsc_uuid.IsValid()) {
- dsc_uuid = GetSharedCacheUUID(dsc_filespec, byte_order, addr_byte_size);
- }
- if (dsc_data_sp) {
- DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
-
- bool uuid_match = true;
- if (dsc_uuid.IsValid() && process) {
- if (process_shared_cache_uuid.IsValid() &&
- dsc_uuid != process_shared_cache_uuid) {
- // The on-disk dyld_shared_cache file is not the same as the one in
- // this process' memory, don't use it.
- uuid_match = false;
- ModuleSP module_sp(GetModule());
- if (module_sp)
- module_sp->ReportWarning("process shared cache does not match "
- "on-disk dyld_shared_cache file, some "
- "symbol names will be missing.");
- }
- }
-
- offset = offsetof(struct lldb_copy_dyld_cache_header_v1, mappingOffset);
-
- uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
-
- // If the mappingOffset points to a location inside the header, we've
- // opened an old dyld shared cache, and should not proceed further.
- if (uuid_match &&
- mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) {
-
- DataBufferSP dsc_mapping_info_data_sp = MapFileData(
- dsc_filespec, sizeof(struct lldb_copy_dyld_cache_mapping_info),
- mappingOffset);
-
- DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp,
- byte_order, addr_byte_size);
- offset = 0;
-
- // The File addresses (from the in-memory Mach-O load commands) for
- // the shared libraries in the shared library cache need to be
- // adjusted by an offset to match up with the dylibOffset identifying
- // field in the dyld_cache_local_symbol_entry's. This offset is
- // recorded in mapping_offset_value.
- const uint64_t mapping_offset_value =
- dsc_mapping_info_data.GetU64(&offset);
-
- offset = offsetof(struct lldb_copy_dyld_cache_header_v1,
- localSymbolsOffset);
- uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
- uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
-
- if (localSymbolsOffset && localSymbolsSize) {
- // Map the local symbols
- DataBufferSP dsc_local_symbols_data_sp =
- MapFileData(dsc_filespec, localSymbolsSize, localSymbolsOffset);
-
- if (dsc_local_symbols_data_sp) {
- DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp,
- byte_order, addr_byte_size);
-
- offset = 0;
-
- typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
- typedef std::map<uint32_t, ConstString> SymbolIndexToName;
- UndefinedNameToDescMap undefined_name_to_desc;
- SymbolIndexToName reexport_shlib_needs_fixup;
-
- // Read the local_symbols_infos struct in one shot
- struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
- dsc_local_symbols_data.GetU32(&offset,
- &local_symbols_info.nlistOffset, 6);
-
- SectionSP text_section_sp(
- section_list->FindSectionByName(GetSegmentNameTEXT()));
-
- uint32_t header_file_offset =
- (text_section_sp->GetFileAddress() - mapping_offset_value);
-
- offset = local_symbols_info.entriesOffset;
- for (uint32_t entry_index = 0;
- entry_index < local_symbols_info.entriesCount;
- entry_index++) {
- struct lldb_copy_dyld_cache_local_symbols_entry
- local_symbols_entry;
- local_symbols_entry.dylibOffset =
- dsc_local_symbols_data.GetU32(&offset);
- local_symbols_entry.nlistStartIndex =
- dsc_local_symbols_data.GetU32(&offset);
- local_symbols_entry.nlistCount =
- dsc_local_symbols_data.GetU32(&offset);
-
- if (header_file_offset == local_symbols_entry.dylibOffset) {
- unmapped_local_symbols_found = local_symbols_entry.nlistCount;
-
- // The normal nlist code cannot correctly size the Symbols
- // array, we need to allocate it here.
- sym = symtab->Resize(
- symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
- unmapped_local_symbols_found - m_dysymtab.nlocalsym);
- num_syms = symtab->GetNumSymbols();
-
- nlist_data_offset =
- local_symbols_info.nlistOffset +
- (nlist_byte_size * local_symbols_entry.nlistStartIndex);
- uint32_t string_table_offset =
- local_symbols_info.stringsOffset;
-
- for (uint32_t nlist_index = 0;
- nlist_index < local_symbols_entry.nlistCount;
- nlist_index++) {
- /////////////////////////////
- {
- struct nlist_64 nlist;
- if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(
- nlist_data_offset, nlist_byte_size))
- break;
-
- nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(
- &nlist_data_offset);
- nlist.n_type = dsc_local_symbols_data.GetU8_unchecked(
- &nlist_data_offset);
- nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked(
- &nlist_data_offset);
- nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked(
- &nlist_data_offset);
- nlist.n_value =
- dsc_local_symbols_data.GetAddress_unchecked(
- &nlist_data_offset);
-
- SymbolType type = eSymbolTypeInvalid;
- const char *symbol_name = dsc_local_symbols_data.PeekCStr(
- string_table_offset + nlist.n_strx);
-
- if (symbol_name == NULL) {
- // No symbol should be NULL, even the symbols with no
- // string values should have an offset zero which
- // points to an empty C-string
- Host::SystemLog(
- Host::eSystemLogError,
- "error: DSC unmapped local symbol[%u] has invalid "
- "string table offset 0x%x in %s, ignoring symbol\n",
- entry_index, nlist.n_strx,
- module_sp->GetFileSpec().GetPath().c_str());
- continue;
- }
- if (symbol_name[0] == '\0')
- symbol_name = NULL;
-
- const char *symbol_name_non_abi_mangled = NULL;
-
- SectionSP symbol_section;
- uint32_t symbol_byte_size = 0;
- bool add_nlist = true;
- bool is_debug = ((nlist.n_type & N_STAB) != 0);
- bool demangled_is_synthesized = false;
- bool is_gsym = false;
- bool set_value = true;
-
- assert(sym_idx < num_syms);
-
- sym[sym_idx].SetDebug(is_debug);
-
- if (is_debug) {
- switch (nlist.n_type) {
- case N_GSYM:
- // global symbol: name,,NO_SECT,type,0
- // Sometimes the N_GSYM value contains the address.
-
- // FIXME: In the .o files, we have a GSYM and a debug
- // symbol for all the ObjC data. They
- // have the same address, but we want to ensure that
- // we always find only the real symbol, 'cause we
- // don't currently correctly attribute the
- // GSYM one to the ObjCClass/Ivar/MetaClass
- // symbol type. This is a temporary hack to make
- // sure the ObjectiveC symbols get treated correctly.
- // To do this right, we should coalesce all the GSYM
- // & global symbols that have the same address.
-
- is_gsym = true;
- sym[sym_idx].SetExternal(true);
-
- if (symbol_name && symbol_name[0] == '_' &&
- symbol_name[1] == 'O') {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.startswith(
- g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- } else if (symbol_name_ref.startswith(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name +
- g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.startswith(
- g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- } else {
- if (nlist.n_value != 0)
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- type = eSymbolTypeData;
- }
- break;
-
- case N_FNAME:
- // procedure name (f77 kludge): name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_FUN:
- // procedure: name,,n_sect,linenumber,address
- if (symbol_name) {
- type = eSymbolTypeCode;
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
-
- N_FUN_addr_to_sym_idx.insert(
- std::make_pair(nlist.n_value, sym_idx));
- // We use the current number of symbols in the
- // symbol table in lieu of using nlist_idx in case
- // we ever start trimming entries out
- N_FUN_indexes.push_back(sym_idx);
- } else {
- type = eSymbolTypeCompiler;
-
- if (!N_FUN_indexes.empty()) {
- // Copy the size of the function into the
- // original
- // STAB entry so we don't have
- // to hunt for it later
- symtab->SymbolAtIndex(N_FUN_indexes.back())
- ->SetByteSize(nlist.n_value);
- N_FUN_indexes.pop_back();
- // We don't really need the end function STAB as
- // it contains the size which we already placed
- // with the original symbol, so don't add it if
- // we want a minimal symbol table
- add_nlist = false;
- }
- }
- break;
-
- case N_STSYM:
- // static symbol: name,,n_sect,type,address
- N_STSYM_addr_to_sym_idx.insert(
- std::make_pair(nlist.n_value, sym_idx));
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- if (symbol_name && symbol_name[0]) {
- type = ObjectFile::GetSymbolTypeFromName(
- symbol_name + 1, eSymbolTypeData);
- }
- break;
-
- case N_LCSYM:
- // .lcomm symbol: name,,n_sect,type,address
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- type = eSymbolTypeCommonBlock;
- break;
-
- case N_BNSYM:
- // We use the current number of symbols in the symbol
- // table in lieu of using nlist_idx in case we ever
- // start trimming entries out Skip these if we want
- // minimal symbol tables
- add_nlist = false;
- break;
-
- case N_ENSYM:
- // Set the size of the N_BNSYM to the terminating
- // index of this N_ENSYM so that we can always skip
- // the entire symbol if we need to navigate more
- // quickly at the source level when parsing STABS
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
-
- case N_OPT:
- // emitted with gcc2_compiled and in gcc source
- type = eSymbolTypeCompiler;
- break;
-
- case N_RSYM:
- // register sym: name,,NO_SECT,type,register
- type = eSymbolTypeVariable;
- break;
-
- case N_SLINE:
- // src line: 0,,n_sect,linenumber,address
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- case N_SSYM:
- // structure elt: name,,NO_SECT,type,struct_offset
- type = eSymbolTypeVariableType;
- break;
-
- case N_SO:
- // source file name
- type = eSymbolTypeSourceFile;
- if (symbol_name == NULL) {
- add_nlist = false;
- if (N_SO_index != UINT32_MAX) {
- // Set the size of the N_SO to the terminating
- // index of this N_SO so that we can always skip
- // the entire N_SO if we need to navigate more
- // quickly at the source level when parsing STABS
- symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
- symbol_ptr->SetByteSize(sym_idx);
- symbol_ptr->SetSizeIsSibling(true);
- }
- N_NSYM_indexes.clear();
- N_INCL_indexes.clear();
- N_BRAC_indexes.clear();
- N_COMM_indexes.clear();
- N_FUN_indexes.clear();
- N_SO_index = UINT32_MAX;
- } else {
- // We use the current number of symbols in the
- // symbol table in lieu of using nlist_idx in case
- // we ever start trimming entries out
- const bool N_SO_has_full_path =
- symbol_name[0] == '/';
- if (N_SO_has_full_path) {
- if ((N_SO_index == sym_idx - 1) &&
- ((sym_idx - 1) < num_syms)) {
- // We have two consecutive N_SO entries where
- // the first contains a directory and the
- // second contains a full path.
- sym[sym_idx - 1].GetMangled().SetValue(
- ConstString(symbol_name), false);
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- add_nlist = false;
- } else {
- // This is the first entry in a N_SO that
- // contains a directory or
- // a full path to the source file
- N_SO_index = sym_idx;
- }
- } else if ((N_SO_index == sym_idx - 1) &&
- ((sym_idx - 1) < num_syms)) {
- // This is usually the second N_SO entry that
- // contains just the filename, so here we combine
- // it with the first one if we are minimizing the
- // symbol table
- const char *so_path =
- sym[sym_idx - 1]
- .GetMangled()
- .GetDemangledName(
- lldb::eLanguageTypeUnknown)
- .AsCString();
- if (so_path && so_path[0]) {
- std::string full_so_path(so_path);
- const size_t double_slash_pos =
- full_so_path.find("//");
- if (double_slash_pos != std::string::npos) {
- // The linker has been generating bad N_SO
- // entries with doubled up paths
- // in the format "%s%s" where the first
- // string in the DW_AT_comp_dir, and the
- // second is the directory for the source
- // file so you end up with a path that looks
- // like "/tmp/src//tmp/src/"
- FileSpec so_dir(so_path, false);
- if (!FileSystem::Instance().Exists(so_dir)) {
- so_dir.SetFile(
- &full_so_path[double_slash_pos + 1],
- false);
- if (FileSystem::Instance().Exists(so_dir)) {
- // Trim off the incorrect path
- full_so_path.erase(0,
- double_slash_pos + 1);
- }
- }
- }
- if (*full_so_path.rbegin() != '/')
- full_so_path += '/';
- full_so_path += symbol_name;
- sym[sym_idx - 1].GetMangled().SetValue(
- ConstString(full_so_path.c_str()), false);
- add_nlist = false;
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- }
- } else {
- // This could be a relative path to a N_SO
- N_SO_index = sym_idx;
- }
- }
- break;
-
- case N_OSO:
- // object file name: name,,0,0,st_mtime
- type = eSymbolTypeObjectFile;
- break;
-
- case N_LSYM:
- // local sym: name,,NO_SECT,type,offset
- type = eSymbolTypeLocal;
- break;
-
- //----------------------------------------------------------------------
- // INCL scopes
- //----------------------------------------------------------------------
- case N_BINCL:
- // include file beginning: name,,NO_SECT,0,sum We use
- // the current number of symbols in the symbol table
- // in lieu of using nlist_idx in case we ever start
- // trimming entries out
- N_INCL_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_EINCL:
- // include file end: name,,NO_SECT,0,0
- // Set the size of the N_BINCL to the terminating
- // index of this N_EINCL so that we can always skip
- // the entire symbol if we need to navigate more
- // quickly at the source level when parsing STABS
- if (!N_INCL_indexes.empty()) {
- symbol_ptr =
- symtab->SymbolAtIndex(N_INCL_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_INCL_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_SOL:
- // #included file name: name,,n_sect,0,address
- type = eSymbolTypeHeaderFile;
-
- // We currently don't use the header files on darwin
- add_nlist = false;
- break;
-
- case N_PARAMS:
- // compiler parameters: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_VERSION:
- // compiler version: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_OLEVEL:
- // compiler -O level: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_PSYM:
- // parameter: name,,NO_SECT,type,offset
- type = eSymbolTypeVariable;
- break;
-
- case N_ENTRY:
- // alternate entry: name,,n_sect,linenumber,address
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- //----------------------------------------------------------------------
- // Left and Right Braces
- //----------------------------------------------------------------------
- case N_LBRAC:
- // left bracket: 0,,NO_SECT,nesting level,address We
- // use the current number of symbols in the symbol
- // table in lieu of using nlist_idx in case we ever
- // start trimming entries out
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- N_BRAC_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_RBRAC:
- // right bracket: 0,,NO_SECT,nesting level,address
- // Set the size of the N_LBRAC to the terminating
- // index of this N_RBRAC so that we can always skip
- // the entire symbol if we need to navigate more
- // quickly at the source level when parsing STABS
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- if (!N_BRAC_indexes.empty()) {
- symbol_ptr =
- symtab->SymbolAtIndex(N_BRAC_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_BRAC_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_EXCL:
- // deleted include file: name,,NO_SECT,0,sum
- type = eSymbolTypeHeaderFile;
- break;
-
- //----------------------------------------------------------------------
- // COMM scopes
- //----------------------------------------------------------------------
- case N_BCOMM:
- // begin common: name,,NO_SECT,0,0
- // We use the current number of symbols in the symbol
- // table in lieu of using nlist_idx in case we ever
- // start trimming entries out
- type = eSymbolTypeScopeBegin;
- N_COMM_indexes.push_back(sym_idx);
- break;
-
- case N_ECOML:
- // end common (local name): 0,,n_sect,0,address
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
- // Fall through
-
- case N_ECOMM:
- // end common: name,,n_sect,0,0
- // Set the size of the N_BCOMM to the terminating
- // index of this N_ECOMM/N_ECOML so that we can
- // always skip the entire symbol if we need to
- // navigate more quickly at the source level when
- // parsing STABS
- if (!N_COMM_indexes.empty()) {
- symbol_ptr =
- symtab->SymbolAtIndex(N_COMM_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_COMM_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_LENG:
- // second stab entry with length information
- type = eSymbolTypeAdditional;
- break;
-
- default:
- break;
- }
- } else {
- // uint8_t n_pext = N_PEXT & nlist.n_type;
- uint8_t n_type = N_TYPE & nlist.n_type;
- sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
-
- switch (n_type) {
- case N_INDR: {
- const char *reexport_name_cstr =
- strtab_data.PeekCStr(nlist.n_value);
- if (reexport_name_cstr && reexport_name_cstr[0]) {
- type = eSymbolTypeReExported;
- ConstString reexport_name(
- reexport_name_cstr +
- ((reexport_name_cstr[0] == '_') ? 1 : 0));
- sym[sym_idx].SetReExportedSymbolName(reexport_name);
- set_value = false;
- reexport_shlib_needs_fixup[sym_idx] = reexport_name;
- indirect_symbol_names.insert(
- ConstString(symbol_name +
- ((symbol_name[0] == '_') ? 1 : 0)));
- } else
- type = eSymbolTypeUndefined;
- } break;
-
- case N_UNDF:
- if (symbol_name && symbol_name[0]) {
- ConstString undefined_name(
- symbol_name +
- ((symbol_name[0] == '_') ? 1 : 0));
- undefined_name_to_desc[undefined_name] =
- nlist.n_desc;
- }
- // Fall through
- case N_PBUD:
- type = eSymbolTypeUndefined;
- break;
-
- case N_ABS:
- type = eSymbolTypeAbsolute;
- break;
-
- case N_SECT: {
- symbol_section = section_info.GetSection(
- nlist.n_sect, nlist.n_value);
-
- if (symbol_section == NULL) {
- // TODO: warn about this?
- add_nlist = false;
- break;
- }
-
- if (TEXT_eh_frame_sectID == nlist.n_sect) {
- type = eSymbolTypeException;
- } else {
- uint32_t section_type =
- symbol_section->Get() & SECTION_TYPE;
-
- switch (section_type) {
- case S_CSTRING_LITERALS:
- type = eSymbolTypeData;
- break; // section with only literal C strings
- case S_4BYTE_LITERALS:
- type = eSymbolTypeData;
- break; // section with only 4 byte literals
- case S_8BYTE_LITERALS:
- type = eSymbolTypeData;
- break; // section with only 8 byte literals
- case S_LITERAL_POINTERS:
- type = eSymbolTypeTrampoline;
- break; // section with only pointers to literals
- case S_NON_LAZY_SYMBOL_POINTERS:
- type = eSymbolTypeTrampoline;
- break; // section with only non-lazy symbol
- // pointers
- case S_LAZY_SYMBOL_POINTERS:
- type = eSymbolTypeTrampoline;
- break; // section with only lazy symbol pointers
- case S_SYMBOL_STUBS:
- type = eSymbolTypeTrampoline;
- break; // section with only symbol stubs, byte
- // size of stub in the reserved2 field
- case S_MOD_INIT_FUNC_POINTERS:
- type = eSymbolTypeCode;
- break; // section with only function pointers for
- // initialization
- case S_MOD_TERM_FUNC_POINTERS:
- type = eSymbolTypeCode;
- break; // section with only function pointers for
- // termination
- case S_INTERPOSING:
- type = eSymbolTypeTrampoline;
- break; // section with only pairs of function
- // pointers for interposing
- case S_16BYTE_LITERALS:
- type = eSymbolTypeData;
- break; // section with only 16 byte literals
- case S_DTRACE_DOF:
- type = eSymbolTypeInstrumentation;
- break;
- case S_LAZY_DYLIB_SYMBOL_POINTERS:
- type = eSymbolTypeTrampoline;
- break;
- default:
- switch (symbol_section->GetType()) {
- case lldb::eSectionTypeCode:
- type = eSymbolTypeCode;
- break;
- case eSectionTypeData:
- case eSectionTypeDataCString: // Inlined C string
- // data
- case eSectionTypeDataCStringPointers: // Pointers
- // to C
- // string
- // data
- case eSectionTypeDataSymbolAddress: // Address of
- // a symbol in
- // the symbol
- // table
- case eSectionTypeData4:
- case eSectionTypeData8:
- case eSectionTypeData16:
- type = eSymbolTypeData;
- break;
- default:
- break;
- }
- break;
- }
-
- if (type == eSymbolTypeInvalid) {
- const char *symbol_sect_name =
- symbol_section->GetName().AsCString();
- if (symbol_section->IsDescendant(
- text_section_sp.get())) {
- if (symbol_section->IsClear(
- S_ATTR_PURE_INSTRUCTIONS |
- S_ATTR_SELF_MODIFYING_CODE |
- S_ATTR_SOME_INSTRUCTIONS))
- type = eSymbolTypeData;
- else
- type = eSymbolTypeCode;
- } else if (symbol_section->IsDescendant(
- data_section_sp.get()) ||
- symbol_section->IsDescendant(
- data_dirty_section_sp.get()) ||
- symbol_section->IsDescendant(
- data_const_section_sp.get())) {
- if (symbol_sect_name &&
- ::strstr(symbol_sect_name, "__objc") ==
- symbol_sect_name) {
- type = eSymbolTypeRuntime;
-
- if (symbol_name) {
- llvm::StringRef symbol_name_ref(
- symbol_name);
- if (symbol_name_ref.startswith("_OBJC_")) {
- static const llvm::StringRef
- g_objc_v2_prefix_class(
- "_OBJC_CLASS_$_");
- static const llvm::StringRef
- g_objc_v2_prefix_metaclass(
- "_OBJC_METACLASS_$_");
- static const llvm::StringRef
- g_objc_v2_prefix_ivar(
- "_OBJC_IVAR_$_");
- if (symbol_name_ref.startswith(
- g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled =
- symbol_name + 1;
- symbol_name =
- symbol_name +
- g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- } else if (
- symbol_name_ref.startswith(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled =
- symbol_name + 1;
- symbol_name =
- symbol_name +
- g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.startswith(
- g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled =
- symbol_name + 1;
- symbol_name =
- symbol_name +
- g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- }
- } else if (symbol_sect_name &&
- ::strstr(symbol_sect_name,
- "__gcc_except_tab") ==
- symbol_sect_name) {
- type = eSymbolTypeException;
- } else {
- type = eSymbolTypeData;
- }
- } else if (symbol_sect_name &&
- ::strstr(symbol_sect_name,
- "__IMPORT") ==
- symbol_sect_name) {
- type = eSymbolTypeTrampoline;
- } else if (symbol_section->IsDescendant(
- objc_section_sp.get())) {
- type = eSymbolTypeRuntime;
- if (symbol_name && symbol_name[0] == '.') {
- llvm::StringRef symbol_name_ref(symbol_name);
- static const llvm::StringRef
- g_objc_v1_prefix_class(
- ".objc_class_name_");
- if (symbol_name_ref.startswith(
- g_objc_v1_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name;
- symbol_name = symbol_name +
- g_objc_v1_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- }
- }
- }
- }
- }
- } break;
- }
- }
-
- if (add_nlist) {
- uint64_t symbol_value = nlist.n_value;
- if (symbol_name_non_abi_mangled) {
- sym[sym_idx].GetMangled().SetMangledName(
- ConstString(symbol_name_non_abi_mangled));
- sym[sym_idx].GetMangled().SetDemangledName(
- ConstString(symbol_name));
- } else {
- bool symbol_name_is_mangled = false;
-
- if (symbol_name && symbol_name[0] == '_') {
- symbol_name_is_mangled = symbol_name[1] == '_';
- symbol_name++; // Skip the leading underscore
- }
-
- if (symbol_name) {
- ConstString const_symbol_name(symbol_name);
- sym[sym_idx].GetMangled().SetValue(
- const_symbol_name, symbol_name_is_mangled);
- if (is_gsym && is_debug) {
- const char *gsym_name =
- sym[sym_idx]
- .GetMangled()
- .GetName(lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)
- .GetCString();
- if (gsym_name)
- N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
- }
- }
- }
- if (symbol_section) {
- const addr_t section_file_addr =
- symbol_section->GetFileAddress();
- if (symbol_byte_size == 0 &&
- function_starts_count > 0) {
- addr_t symbol_lookup_file_addr = nlist.n_value;
- // Do an exact address match for non-ARM addresses,
- // else get the closest since the symbol might be a
- // thumb symbol which has an address with bit zero
- // set
- FunctionStarts::Entry *func_start_entry =
- function_starts.FindEntry(
- symbol_lookup_file_addr, !is_arm);
- if (is_arm && func_start_entry) {
- // Verify that the function start address is the
- // symbol address (ARM) or the symbol address + 1
- // (thumb)
- if (func_start_entry->addr !=
- symbol_lookup_file_addr &&
- func_start_entry->addr !=
- (symbol_lookup_file_addr + 1)) {
- // Not the right entry, NULL it out...
- func_start_entry = NULL;
- }
- }
- if (func_start_entry) {
- func_start_entry->data = true;
-
- addr_t symbol_file_addr = func_start_entry->addr;
- uint32_t symbol_flags = 0;
- if (is_arm) {
- if (symbol_file_addr & 1)
- symbol_flags =
- MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
- symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- }
-
- const FunctionStarts::Entry
- *next_func_start_entry =
- function_starts.FindNextEntry(
- func_start_entry);
- const addr_t section_end_file_addr =
- section_file_addr +
- symbol_section->GetByteSize();
- if (next_func_start_entry) {
- addr_t next_symbol_file_addr =
- next_func_start_entry->addr;
- // Be sure the clear the Thumb address bit when
- // we calculate the size from the current and
- // next address
- if (is_arm)
- next_symbol_file_addr &=
- THUMB_ADDRESS_BIT_MASK;
- symbol_byte_size = std::min<lldb::addr_t>(
- next_symbol_file_addr - symbol_file_addr,
- section_end_file_addr - symbol_file_addr);
- } else {
- symbol_byte_size =
- section_end_file_addr - symbol_file_addr;
- }
- }
- }
- symbol_value -= section_file_addr;
- }
-
- if (is_debug == false) {
- if (type == eSymbolTypeCode) {
- // See if we can find a N_FUN entry for any code
- // symbols. If we do find a match, and the name
- // matches, then we can merge the two into just the
- // function symbol to avoid duplicate entries in
- // the symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator,
- ValueToSymbolIndexMap::const_iterator>
- range;
- range = N_FUN_addr_to_sym_idx.equal_range(
- nlist.n_value);
- if (range.first != range.second) {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos =
- range.first;
- pos != range.second; ++pos) {
- if (sym[sym_idx].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled) ==
- sym[pos->second].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)) {
- m_nlist_idx_to_sym_idx[nlist_idx] =
- pos->second;
- // We just need the flags from the linker
- // symbol, so put these flags
- // into the N_FUN flags to avoid duplicate
- // symbols in the symbol table
- sym[pos->second].SetExternal(
- sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags(nlist.n_type << 16 |
- nlist.n_desc);
- if (resolver_addresses.find(nlist.n_value) !=
- resolver_addresses.end())
- sym[pos->second].SetType(
- eSymbolTypeResolver);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
- }
- if (found_it)
- continue;
- } else {
- if (resolver_addresses.find(nlist.n_value) !=
- resolver_addresses.end())
- type = eSymbolTypeResolver;
- }
- } else if (type == eSymbolTypeData ||
- type == eSymbolTypeObjCClass ||
- type == eSymbolTypeObjCMetaClass ||
- type == eSymbolTypeObjCIVar) {
- // See if we can find a N_STSYM entry for any data
- // symbols. If we do find a match, and the name
- // matches, then we can merge the two into just the
- // Static symbol to avoid duplicate entries in the
- // symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator,
- ValueToSymbolIndexMap::const_iterator>
- range;
- range = N_STSYM_addr_to_sym_idx.equal_range(
- nlist.n_value);
- if (range.first != range.second) {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos =
- range.first;
- pos != range.second; ++pos) {
- if (sym[sym_idx].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled) ==
- sym[pos->second].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)) {
- m_nlist_idx_to_sym_idx[nlist_idx] =
- pos->second;
- // We just need the flags from the linker
- // symbol, so put these flags
- // into the N_STSYM flags to avoid duplicate
- // symbols in the symbol table
- sym[pos->second].SetExternal(
- sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags(nlist.n_type << 16 |
- nlist.n_desc);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
- }
- if (found_it)
- continue;
- } else {
- const char *gsym_name =
- sym[sym_idx]
- .GetMangled()
- .GetName(lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)
- .GetCString();
- if (gsym_name) {
- // Combine N_GSYM stab entries with the non
- // stab symbol
- ConstNameToSymbolIndexMap::const_iterator pos =
- N_GSYM_name_to_sym_idx.find(gsym_name);
- if (pos != N_GSYM_name_to_sym_idx.end()) {
- const uint32_t GSYM_sym_idx = pos->second;
- m_nlist_idx_to_sym_idx[nlist_idx] =
- GSYM_sym_idx;
- // Copy the address, because often the N_GSYM
- // address has an invalid address of zero
- // when the global is a common symbol
- sym[GSYM_sym_idx].GetAddressRef().SetSection(
- symbol_section);
- sym[GSYM_sym_idx].GetAddressRef().SetOffset(
- symbol_value);
- // We just need the flags from the linker
- // symbol, so put these flags
- // into the N_GSYM flags to avoid duplicate
- // symbols in the symbol table
- sym[GSYM_sym_idx].SetFlags(
- nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- continue;
- }
- }
- }
- }
- }
-
- sym[sym_idx].SetID(nlist_idx);
- sym[sym_idx].SetType(type);
- if (set_value) {
- sym[sym_idx].GetAddressRef().SetSection(
- symbol_section);
- sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
- }
- sym[sym_idx].SetFlags(nlist.n_type << 16 |
- nlist.n_desc);
-
- if (symbol_byte_size > 0)
- sym[sym_idx].SetByteSize(symbol_byte_size);
-
- if (demangled_is_synthesized)
- sym[sym_idx].SetDemangledNameIsSynthesized(true);
- ++sym_idx;
- } else {
- sym[sym_idx].Clear();
- }
- }
- /////////////////////////////
- }
- break; // No more entries to consider
- }
- }
-
- for (const auto &pos : reexport_shlib_needs_fixup) {
- const auto undef_pos = undefined_name_to_desc.find(pos.second);
- if (undef_pos != undefined_name_to_desc.end()) {
- const uint8_t dylib_ordinal =
- llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
- if (dylib_ordinal > 0 &&
- dylib_ordinal < dylib_files.GetSize())
- sym[pos.first].SetReExportedSymbolSharedLibrary(
- dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
- }
- }
- }
- }
- }
- }
- }
-
- // Must reset this in case it was mutated above!
- nlist_data_offset = 0;
-#endif
-
- if (nlist_data.GetByteSize() > 0) {
-
- // If the sym array was not created while parsing the DSC unmapped
- // symbols, create it now.
- if (sym == NULL) {
- sym = symtab->Resize(symtab_load_command.nsyms +
- m_dysymtab.nindirectsyms);
- num_syms = symtab->GetNumSymbols();
- }
-
- if (unmapped_local_symbols_found) {
- assert(m_dysymtab.ilocalsym == 0);
- nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
- nlist_idx = m_dysymtab.nlocalsym;
- } else {
- nlist_idx = 0;
- }
-
- typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
- typedef std::map<uint32_t, ConstString> SymbolIndexToName;
- UndefinedNameToDescMap undefined_name_to_desc;
- SymbolIndexToName reexport_shlib_needs_fixup;
- for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
- struct nlist_64 nlist;
- if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset,
- nlist_byte_size))
- break;
-
- nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
- nlist.n_type = nlist_data.GetU8_unchecked(&nlist_data_offset);
- nlist.n_sect = nlist_data.GetU8_unchecked(&nlist_data_offset);
- nlist.n_desc = nlist_data.GetU16_unchecked(&nlist_data_offset);
- nlist.n_value = nlist_data.GetAddress_unchecked(&nlist_data_offset);
-
- SymbolType type = eSymbolTypeInvalid;
- const char *symbol_name = NULL;
-
- if (have_strtab_data) {
- symbol_name = strtab_data.PeekCStr(nlist.n_strx);
-
- if (symbol_name == NULL) {
- // No symbol should be NULL, even the symbols with no string values
- // should have an offset zero which points to an empty C-string
- Host::SystemLog(Host::eSystemLogError,
- "error: symbol[%u] has invalid string table offset "
- "0x%x in %s, ignoring symbol\n",
- nlist_idx, nlist.n_strx,
- module_sp->GetFileSpec().GetPath().c_str());
- continue;
- }
- if (symbol_name[0] == '\0')
- symbol_name = NULL;
- } else {
- const addr_t str_addr = strtab_addr + nlist.n_strx;
- Status str_error;
- if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
- str_error))
- symbol_name = memory_symbol_name.c_str();
- }
- const char *symbol_name_non_abi_mangled = NULL;
-
- SectionSP symbol_section;
- lldb::addr_t symbol_byte_size = 0;
- bool add_nlist = true;
- bool is_gsym = false;
- bool is_debug = ((nlist.n_type & N_STAB) != 0);
- bool demangled_is_synthesized = false;
- bool set_value = true;
- assert(sym_idx < num_syms);
-
- sym[sym_idx].SetDebug(is_debug);
-
- if (is_debug) {
- switch (nlist.n_type) {
- case N_GSYM:
- // global symbol: name,,NO_SECT,type,0
- // Sometimes the N_GSYM value contains the address.
-
- // FIXME: In the .o files, we have a GSYM and a debug symbol for all
- // the ObjC data. They
- // have the same address, but we want to ensure that we always find
- // only the real symbol, 'cause we don't currently correctly
- // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol
- // type. This is a temporary hack to make sure the ObjectiveC
- // symbols get treated correctly. To do this right, we should
- // coalesce all the GSYM & global symbols that have the same
- // address.
- is_gsym = true;
- sym[sym_idx].SetExternal(true);
-
- if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O') {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- } else if (symbol_name_ref.startswith(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- } else {
- if (nlist.n_value != 0)
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- type = eSymbolTypeData;
- }
- break;
-
- case N_FNAME:
- // procedure name (f77 kludge): name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_FUN:
- // procedure: name,,n_sect,linenumber,address
- if (symbol_name) {
- type = eSymbolTypeCode;
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
-
- N_FUN_addr_to_sym_idx.insert(
- std::make_pair(nlist.n_value, sym_idx));
- // We use the current number of symbols in the symbol table in
- // lieu of using nlist_idx in case we ever start trimming entries
- // out
- N_FUN_indexes.push_back(sym_idx);
- } else {
- type = eSymbolTypeCompiler;
-
- if (!N_FUN_indexes.empty()) {
- // Copy the size of the function into the original STAB entry
- // so we don't have to hunt for it later
- symtab->SymbolAtIndex(N_FUN_indexes.back())
- ->SetByteSize(nlist.n_value);
- N_FUN_indexes.pop_back();
- // We don't really need the end function STAB as it contains
- // the size which we already placed with the original symbol,
- // so don't add it if we want a minimal symbol table
- add_nlist = false;
- }
- }
- break;
-
- case N_STSYM:
- // static symbol: name,,n_sect,type,address
- N_STSYM_addr_to_sym_idx.insert(
- std::make_pair(nlist.n_value, sym_idx));
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- if (symbol_name && symbol_name[0]) {
- type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
- eSymbolTypeData);
- }
- break;
-
- case N_LCSYM:
- // .lcomm symbol: name,,n_sect,type,address
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- type = eSymbolTypeCommonBlock;
- break;
-
- case N_BNSYM:
- // We use the current number of symbols in the symbol table in lieu
- // of using nlist_idx in case we ever start trimming entries out
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
-
- case N_ENSYM:
- // Set the size of the N_BNSYM to the terminating index of this
- // N_ENSYM so that we can always skip the entire symbol if we need
- // to navigate more quickly at the source level when parsing STABS
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
-
- case N_OPT:
- // emitted with gcc2_compiled and in gcc source
- type = eSymbolTypeCompiler;
- break;
-
- case N_RSYM:
- // register sym: name,,NO_SECT,type,register
- type = eSymbolTypeVariable;
- break;
-
- case N_SLINE:
- // src line: 0,,n_sect,linenumber,address
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- case N_SSYM:
- // structure elt: name,,NO_SECT,type,struct_offset
- type = eSymbolTypeVariableType;
- break;
-
- case N_SO:
- // source file name
- type = eSymbolTypeSourceFile;
- if (symbol_name == NULL) {
- add_nlist = false;
- if (N_SO_index != UINT32_MAX) {
- // Set the size of the N_SO to the terminating index of this
- // N_SO so that we can always skip the entire N_SO if we need
- // to navigate more quickly at the source level when parsing
- // STABS
- symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
- symbol_ptr->SetByteSize(sym_idx);
- symbol_ptr->SetSizeIsSibling(true);
- }
- N_NSYM_indexes.clear();
- N_INCL_indexes.clear();
- N_BRAC_indexes.clear();
- N_COMM_indexes.clear();
- N_FUN_indexes.clear();
- N_SO_index = UINT32_MAX;
- } else {
- // We use the current number of symbols in the symbol table in
- // lieu of using nlist_idx in case we ever start trimming entries
- // out
- const bool N_SO_has_full_path = symbol_name[0] == '/';
- if (N_SO_has_full_path) {
- if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
- // We have two consecutive N_SO entries where the first
- // contains a directory and the second contains a full path.
- sym[sym_idx - 1].GetMangled().SetValue(
- ConstString(symbol_name), false);
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- add_nlist = false;
- } else {
- // This is the first entry in a N_SO that contains a
- // directory or a full path to the source file
- N_SO_index = sym_idx;
- }
- } else if ((N_SO_index == sym_idx - 1) &&
- ((sym_idx - 1) < num_syms)) {
- // This is usually the second N_SO entry that contains just the
- // filename, so here we combine it with the first one if we are
- // minimizing the symbol table
- const char *so_path =
- sym[sym_idx - 1]
- .GetMangled()
- .GetDemangledName(lldb::eLanguageTypeUnknown)
- .AsCString();
- if (so_path && so_path[0]) {
- std::string full_so_path(so_path);
- const size_t double_slash_pos = full_so_path.find("//");
- if (double_slash_pos != std::string::npos) {
- // The linker has been generating bad N_SO entries with
- // doubled up paths in the format "%s%s" where the first
- // string in the DW_AT_comp_dir, and the second is the
- // directory for the source file so you end up with a path
- // that looks like "/tmp/src//tmp/src/"
- FileSpec so_dir(so_path);
- if (!FileSystem::Instance().Exists(so_dir)) {
- so_dir.SetFile(&full_so_path[double_slash_pos + 1],
- FileSpec::Style::native);
- if (FileSystem::Instance().Exists(so_dir)) {
- // Trim off the incorrect path
- full_so_path.erase(0, double_slash_pos + 1);
- }
- }
- }
- if (*full_so_path.rbegin() != '/')
- full_so_path += '/';
- full_so_path += symbol_name;
- sym[sym_idx - 1].GetMangled().SetValue(
- ConstString(full_so_path.c_str()), false);
- add_nlist = false;
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- }
- } else {
- // This could be a relative path to a N_SO
- N_SO_index = sym_idx;
- }
- }
- break;
-
- case N_OSO:
- // object file name: name,,0,0,st_mtime
- type = eSymbolTypeObjectFile;
- break;
-
- case N_LSYM:
- // local sym: name,,NO_SECT,type,offset
- type = eSymbolTypeLocal;
- break;
-
- //----------------------------------------------------------------------
- // INCL scopes
- //----------------------------------------------------------------------
- case N_BINCL:
- // include file beginning: name,,NO_SECT,0,sum We use the current
- // number of symbols in the symbol table in lieu of using nlist_idx
- // in case we ever start trimming entries out
- N_INCL_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_EINCL:
- // include file end: name,,NO_SECT,0,0
- // Set the size of the N_BINCL to the terminating index of this
- // N_EINCL so that we can always skip the entire symbol if we need
- // to navigate more quickly at the source level when parsing STABS
- if (!N_INCL_indexes.empty()) {
- symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_INCL_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_SOL:
- // #included file name: name,,n_sect,0,address
- type = eSymbolTypeHeaderFile;
-
- // We currently don't use the header files on darwin
- add_nlist = false;
- break;
-
- case N_PARAMS:
- // compiler parameters: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_VERSION:
- // compiler version: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_OLEVEL:
- // compiler -O level: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_PSYM:
- // parameter: name,,NO_SECT,type,offset
- type = eSymbolTypeVariable;
- break;
-
- case N_ENTRY:
- // alternate entry: name,,n_sect,linenumber,address
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- //----------------------------------------------------------------------
- // Left and Right Braces
- //----------------------------------------------------------------------
- case N_LBRAC:
- // left bracket: 0,,NO_SECT,nesting level,address We use the
- // current number of symbols in the symbol table in lieu of using
- // nlist_idx in case we ever start trimming entries out
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- N_BRAC_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_RBRAC:
- // right bracket: 0,,NO_SECT,nesting level,address Set the size of
- // the N_LBRAC to the terminating index of this N_RBRAC so that we
- // can always skip the entire symbol if we need to navigate more
- // quickly at the source level when parsing STABS
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- if (!N_BRAC_indexes.empty()) {
- symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_BRAC_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_EXCL:
- // deleted include file: name,,NO_SECT,0,sum
- type = eSymbolTypeHeaderFile;
- break;
-
- //----------------------------------------------------------------------
- // COMM scopes
- //----------------------------------------------------------------------
- case N_BCOMM:
- // begin common: name,,NO_SECT,0,0
- // We use the current number of symbols in the symbol table in lieu
- // of using nlist_idx in case we ever start trimming entries out
- type = eSymbolTypeScopeBegin;
- N_COMM_indexes.push_back(sym_idx);
- break;
-
- case N_ECOML:
- // end common (local name): 0,,n_sect,0,address
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
- LLVM_FALLTHROUGH;
-
- case N_ECOMM:
- // end common: name,,n_sect,0,0
- // Set the size of the N_BCOMM to the terminating index of this
- // N_ECOMM/N_ECOML so that we can always skip the entire symbol if
- // we need to navigate more quickly at the source level when
- // parsing STABS
- if (!N_COMM_indexes.empty()) {
- symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_COMM_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_LENG:
- // second stab entry with length information
- type = eSymbolTypeAdditional;
- break;
-
- default:
- break;
- }
- } else {
- // uint8_t n_pext = N_PEXT & nlist.n_type;
- uint8_t n_type = N_TYPE & nlist.n_type;
- sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
-
- switch (n_type) {
- case N_INDR: {
- const char *reexport_name_cstr =
- strtab_data.PeekCStr(nlist.n_value);
- if (reexport_name_cstr && reexport_name_cstr[0]) {
- type = eSymbolTypeReExported;
- ConstString reexport_name(
- reexport_name_cstr +
- ((reexport_name_cstr[0] == '_') ? 1 : 0));
- sym[sym_idx].SetReExportedSymbolName(reexport_name);
- set_value = false;
- reexport_shlib_needs_fixup[sym_idx] = reexport_name;
- indirect_symbol_names.insert(
- ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
- } else
- type = eSymbolTypeUndefined;
- } break;
-
- case N_UNDF:
- if (symbol_name && symbol_name[0]) {
- ConstString undefined_name(symbol_name +
- ((symbol_name[0] == '_') ? 1 : 0));
- undefined_name_to_desc[undefined_name] = nlist.n_desc;
- }
- LLVM_FALLTHROUGH;
-
- case N_PBUD:
- type = eSymbolTypeUndefined;
- break;
-
- case N_ABS:
- type = eSymbolTypeAbsolute;
- break;
-
- case N_SECT: {
- symbol_section =
- section_info.GetSection(nlist.n_sect, nlist.n_value);
-
- if (!symbol_section) {
- // TODO: warn about this?
- add_nlist = false;
- break;
- }
-
- if (TEXT_eh_frame_sectID == nlist.n_sect) {
- type = eSymbolTypeException;
- } else {
- uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
-
- switch (section_type) {
- case S_CSTRING_LITERALS:
- type = eSymbolTypeData;
- break; // section with only literal C strings
- case S_4BYTE_LITERALS:
- type = eSymbolTypeData;
- break; // section with only 4 byte literals
- case S_8BYTE_LITERALS:
- type = eSymbolTypeData;
- break; // section with only 8 byte literals
- case S_LITERAL_POINTERS:
- type = eSymbolTypeTrampoline;
- break; // section with only pointers to literals
- case S_NON_LAZY_SYMBOL_POINTERS:
- type = eSymbolTypeTrampoline;
- break; // section with only non-lazy symbol pointers
- case S_LAZY_SYMBOL_POINTERS:
- type = eSymbolTypeTrampoline;
- break; // section with only lazy symbol pointers
- case S_SYMBOL_STUBS:
- type = eSymbolTypeTrampoline;
- break; // section with only symbol stubs, byte size of stub in
- // the reserved2 field
- case S_MOD_INIT_FUNC_POINTERS:
- type = eSymbolTypeCode;
- break; // section with only function pointers for initialization
- case S_MOD_TERM_FUNC_POINTERS:
- type = eSymbolTypeCode;
- break; // section with only function pointers for termination
- case S_INTERPOSING:
- type = eSymbolTypeTrampoline;
- break; // section with only pairs of function pointers for
- // interposing
- case S_16BYTE_LITERALS:
- type = eSymbolTypeData;
- break; // section with only 16 byte literals
- case S_DTRACE_DOF:
- type = eSymbolTypeInstrumentation;
- break;
- case S_LAZY_DYLIB_SYMBOL_POINTERS:
- type = eSymbolTypeTrampoline;
- break;
- default:
- switch (symbol_section->GetType()) {
- case lldb::eSectionTypeCode:
- type = eSymbolTypeCode;
- break;
- case eSectionTypeData:
- case eSectionTypeDataCString: // Inlined C string data
- case eSectionTypeDataCStringPointers: // Pointers to C string
- // data
- case eSectionTypeDataSymbolAddress: // Address of a symbol in
- // the symbol table
- case eSectionTypeData4:
- case eSectionTypeData8:
- case eSectionTypeData16:
- type = eSymbolTypeData;
- break;
- default:
- break;
- }
- break;
- }
-
- if (type == eSymbolTypeInvalid) {
- const char *symbol_sect_name =
- symbol_section->GetName().AsCString();
- if (symbol_section->IsDescendant(text_section_sp.get())) {
- if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
- S_ATTR_SELF_MODIFYING_CODE |
- S_ATTR_SOME_INSTRUCTIONS))
- type = eSymbolTypeData;
- else
- type = eSymbolTypeCode;
- } else if (symbol_section->IsDescendant(
- data_section_sp.get()) ||
- symbol_section->IsDescendant(
- data_dirty_section_sp.get()) ||
- symbol_section->IsDescendant(
- data_const_section_sp.get())) {
- if (symbol_sect_name &&
- ::strstr(symbol_sect_name, "__objc") ==
- symbol_sect_name) {
- type = eSymbolTypeRuntime;
-
- if (symbol_name) {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.startswith("_OBJC_")) {
- static const llvm::StringRef g_objc_v2_prefix_class(
- "_OBJC_CLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_metaclass(
- "_OBJC_METACLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_ivar(
- "_OBJC_IVAR_$_");
- if (symbol_name_ref.startswith(
- g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.startswith(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.startswith(
- g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- }
- } else if (symbol_sect_name &&
- ::strstr(symbol_sect_name, "__gcc_except_tab") ==
- symbol_sect_name) {
- type = eSymbolTypeException;
- } else {
- type = eSymbolTypeData;
- }
- } else if (symbol_sect_name &&
- ::strstr(symbol_sect_name, "__IMPORT") ==
- symbol_sect_name) {
- type = eSymbolTypeTrampoline;
- } else if (symbol_section->IsDescendant(
- objc_section_sp.get())) {
- type = eSymbolTypeRuntime;
- if (symbol_name && symbol_name[0] == '.') {
- llvm::StringRef symbol_name_ref(symbol_name);
- static const llvm::StringRef g_objc_v1_prefix_class(
- ".objc_class_name_");
- if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name;
- symbol_name = symbol_name + g_objc_v1_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- }
- }
- }
- }
- }
- } break;
- }
- }
-
- if (add_nlist) {
- uint64_t symbol_value = nlist.n_value;
-
- if (symbol_name_non_abi_mangled) {
- sym[sym_idx].GetMangled().SetMangledName(
- ConstString(symbol_name_non_abi_mangled));
- sym[sym_idx].GetMangled().SetDemangledName(
- ConstString(symbol_name));
- } else {
- bool symbol_name_is_mangled = false;
-
- if (symbol_name && symbol_name[0] == '_') {
- symbol_name_is_mangled = symbol_name[1] == '_';
- symbol_name++; // Skip the leading underscore
- }
-
- if (symbol_name) {
- ConstString const_symbol_name(symbol_name);
- sym[sym_idx].GetMangled().SetValue(const_symbol_name,
- symbol_name_is_mangled);
- }
- }
-
- if (is_gsym) {
- const char *gsym_name = sym[sym_idx]
- .GetMangled()
- .GetName(lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)
- .GetCString();
- if (gsym_name)
- N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
- }
-
- if (symbol_section) {
- const addr_t section_file_addr = symbol_section->GetFileAddress();
- if (symbol_byte_size == 0 && function_starts_count > 0) {
- addr_t symbol_lookup_file_addr = nlist.n_value;
- // Do an exact address match for non-ARM addresses, else get the
- // closest since the symbol might be a thumb symbol which has an
- // address with bit zero set
- FunctionStarts::Entry *func_start_entry =
- function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
- if (is_arm && func_start_entry) {
- // Verify that the function start address is the symbol address
- // (ARM) or the symbol address + 1 (thumb)
- if (func_start_entry->addr != symbol_lookup_file_addr &&
- func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
- // Not the right entry, NULL it out...
- func_start_entry = NULL;
- }
- }
- if (func_start_entry) {
- func_start_entry->data = true;
-
- addr_t symbol_file_addr = func_start_entry->addr;
- if (is_arm)
- symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
-
- const FunctionStarts::Entry *next_func_start_entry =
- function_starts.FindNextEntry(func_start_entry);
- const addr_t section_end_file_addr =
- section_file_addr + symbol_section->GetByteSize();
- if (next_func_start_entry) {
- addr_t next_symbol_file_addr = next_func_start_entry->addr;
- // Be sure the clear the Thumb address bit when we calculate
- // the size from the current and next address
- if (is_arm)
- next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- symbol_byte_size = std::min<lldb::addr_t>(
- next_symbol_file_addr - symbol_file_addr,
- section_end_file_addr - symbol_file_addr);
- } else {
- symbol_byte_size = section_end_file_addr - symbol_file_addr;
- }
- }
- }
- symbol_value -= section_file_addr;
- }
-
- if (!is_debug) {
- if (type == eSymbolTypeCode) {
- // See if we can find a N_FUN entry for any code symbols. If we
- // do find a match, and the name matches, then we can merge the
- // two into just the function symbol to avoid duplicate entries
- // in the symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator,
- ValueToSymbolIndexMap::const_iterator>
- range;
- range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
- if (range.first != range.second) {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos = range.first;
- pos != range.second; ++pos) {
- if (sym[sym_idx].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled) ==
- sym[pos->second].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)) {
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put
- // these flags into the N_FUN flags to avoid duplicate
- // symbols in the symbol table
- sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags(nlist.n_type << 16 |
- nlist.n_desc);
- if (resolver_addresses.find(nlist.n_value) !=
- resolver_addresses.end())
- sym[pos->second].SetType(eSymbolTypeResolver);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
- }
- if (found_it)
- continue;
- } else {
- if (resolver_addresses.find(nlist.n_value) !=
- resolver_addresses.end())
- type = eSymbolTypeResolver;
- }
- } else if (type == eSymbolTypeData ||
- type == eSymbolTypeObjCClass ||
- type == eSymbolTypeObjCMetaClass ||
- type == eSymbolTypeObjCIVar) {
- // See if we can find a N_STSYM entry for any data symbols. If we
- // do find a match, and the name matches, then we can merge the
- // two into just the Static symbol to avoid duplicate entries in
- // the symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator,
- ValueToSymbolIndexMap::const_iterator>
- range;
- range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
- if (range.first != range.second) {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos = range.first;
- pos != range.second; ++pos) {
- if (sym[sym_idx].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled) ==
- sym[pos->second].GetMangled().GetName(
- lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)) {
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put
- // these flags into the N_STSYM flags to avoid duplicate
- // symbols in the symbol table
- sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags(nlist.n_type << 16 |
- nlist.n_desc);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
- }
- if (found_it)
- continue;
- } else {
- // Combine N_GSYM stab entries with the non stab symbol
- const char *gsym_name = sym[sym_idx]
- .GetMangled()
- .GetName(lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled)
- .GetCString();
- if (gsym_name) {
- ConstNameToSymbolIndexMap::const_iterator pos =
- N_GSYM_name_to_sym_idx.find(gsym_name);
- if (pos != N_GSYM_name_to_sym_idx.end()) {
- const uint32_t GSYM_sym_idx = pos->second;
- m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
- // Copy the address, because often the N_GSYM address has
- // an invalid address of zero when the global is a common
- // symbol
- sym[GSYM_sym_idx].GetAddressRef().SetSection(
- symbol_section);
- sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value);
- // We just need the flags from the linker symbol, so put
- // these flags into the N_GSYM flags to avoid duplicate
- // symbols in the symbol table
- sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
- nlist.n_desc);
- sym[sym_idx].Clear();
- continue;
- }
- }
- }
- }
- }
-
- sym[sym_idx].SetID(nlist_idx);
- sym[sym_idx].SetType(type);
- if (set_value) {
- sym[sym_idx].GetAddressRef().SetSection(symbol_section);
- sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
- }
- sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
-
- if (symbol_byte_size > 0)
- sym[sym_idx].SetByteSize(symbol_byte_size);
-
- if (demangled_is_synthesized)
- sym[sym_idx].SetDemangledNameIsSynthesized(true);
-
- ++sym_idx;
- } else {
- sym[sym_idx].Clear();
- }
- }
-
- for (const auto &pos : reexport_shlib_needs_fixup) {
- const auto undef_pos = undefined_name_to_desc.find(pos.second);
- if (undef_pos != undefined_name_to_desc.end()) {
- const uint8_t dylib_ordinal =
- llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
- if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
- sym[pos.first].SetReExportedSymbolSharedLibrary(
- dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
- }
- }
- }
-
- uint32_t synthetic_sym_id = symtab_load_command.nsyms;
-
- if (function_starts_count > 0) {
- uint32_t num_synthetic_function_symbols = 0;
- for (i = 0; i < function_starts_count; ++i) {
- if (!function_starts.GetEntryRef(i).data)
- ++num_synthetic_function_symbols;
- }
-
- if (num_synthetic_function_symbols > 0) {
- if (num_syms < sym_idx + num_synthetic_function_symbols) {
- num_syms = sym_idx + num_synthetic_function_symbols;
- sym = symtab->Resize(num_syms);
- }
- for (i = 0; i < function_starts_count; ++i) {
- const FunctionStarts::Entry *func_start_entry =
- function_starts.GetEntryAtIndex(i);
- if (!func_start_entry->data) {
- addr_t symbol_file_addr = func_start_entry->addr;
- uint32_t symbol_flags = 0;
- if (is_arm) {
- if (symbol_file_addr & 1)
- symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
- symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- }
- Address symbol_addr;
- if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
- SectionSP symbol_section(symbol_addr.GetSection());
- uint32_t symbol_byte_size = 0;
- if (symbol_section) {
- const addr_t section_file_addr =
- symbol_section->GetFileAddress();
- const FunctionStarts::Entry *next_func_start_entry =
- function_starts.FindNextEntry(func_start_entry);
- const addr_t section_end_file_addr =
- section_file_addr + symbol_section->GetByteSize();
- if (next_func_start_entry) {
- addr_t next_symbol_file_addr = next_func_start_entry->addr;
- if (is_arm)
- next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- symbol_byte_size = std::min<lldb::addr_t>(
- next_symbol_file_addr - symbol_file_addr,
- section_end_file_addr - symbol_file_addr);
- } else {
- symbol_byte_size = section_end_file_addr - symbol_file_addr;
- }
- sym[sym_idx].SetID(synthetic_sym_id++);
- sym[sym_idx].GetMangled().SetDemangledName(
- GetNextSyntheticSymbolName());
- sym[sym_idx].SetType(eSymbolTypeCode);
- sym[sym_idx].SetIsSynthetic(true);
- sym[sym_idx].GetAddressRef() = symbol_addr;
- if (symbol_flags)
- sym[sym_idx].SetFlags(symbol_flags);
- if (symbol_byte_size)
- sym[sym_idx].SetByteSize(symbol_byte_size);
- ++sym_idx;
- }
- }
- }
- }
- }
- }
-
- // Trim our symbols down to just what we ended up with after removing any
- // symbols.
- if (sym_idx < num_syms) {
- num_syms = sym_idx;
- sym = symtab->Resize(num_syms);
- }
-
- // Now synthesize indirect symbols
- if (m_dysymtab.nindirectsyms != 0) {
- if (indirect_symbol_index_data.GetByteSize()) {
- NListIndexToSymbolIndexMap::const_iterator end_index_pos =
- m_nlist_idx_to_sym_idx.end();
-
- for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
- ++sect_idx) {
- if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
- S_SYMBOL_STUBS) {
- uint32_t symbol_stub_byte_size =
- m_mach_sections[sect_idx].reserved2;
- if (symbol_stub_byte_size == 0)
- continue;
-
- const uint32_t num_symbol_stubs =
- m_mach_sections[sect_idx].size / symbol_stub_byte_size;
-
- if (num_symbol_stubs == 0)
- continue;
-
- const uint32_t symbol_stub_index_offset =
- m_mach_sections[sect_idx].reserved1;
- for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs;
- ++stub_idx) {
- const uint32_t symbol_stub_index =
- symbol_stub_index_offset + stub_idx;
- const lldb::addr_t symbol_stub_addr =
- m_mach_sections[sect_idx].addr +
- (stub_idx * symbol_stub_byte_size);
- lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
- if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
- symbol_stub_offset, 4)) {
- const uint32_t stub_sym_id =
- indirect_symbol_index_data.GetU32(&symbol_stub_offset);
- if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
- continue;
-
- NListIndexToSymbolIndexMap::const_iterator index_pos =
- m_nlist_idx_to_sym_idx.find(stub_sym_id);
- Symbol *stub_symbol = NULL;
- if (index_pos != end_index_pos) {
- // We have a remapping from the original nlist index to a
- // current symbol index, so just look this up by index
- stub_symbol = symtab->SymbolAtIndex(index_pos->second);
- } else {
- // We need to lookup a symbol using the original nlist symbol
- // index since this index is coming from the S_SYMBOL_STUBS
- stub_symbol = symtab->FindSymbolByID(stub_sym_id);
- }
-
- if (stub_symbol) {
- Address so_addr(symbol_stub_addr, section_list);
-
- if (stub_symbol->GetType() == eSymbolTypeUndefined) {
- // Change the external symbol into a trampoline that makes
- // sense These symbols were N_UNDF N_EXT, and are useless
- // to us, so we can re-use them so we don't have to make up
- // a synthetic symbol for no good reason.
- if (resolver_addresses.find(symbol_stub_addr) ==
- resolver_addresses.end())
- stub_symbol->SetType(eSymbolTypeTrampoline);
- else
- stub_symbol->SetType(eSymbolTypeResolver);
- stub_symbol->SetExternal(false);
- stub_symbol->GetAddressRef() = so_addr;
- stub_symbol->SetByteSize(symbol_stub_byte_size);
- } else {
- // Make a synthetic symbol to describe the trampoline stub
- Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
- if (sym_idx >= num_syms) {
- sym = symtab->Resize(++num_syms);
- stub_symbol = NULL; // this pointer no longer valid
- }
- sym[sym_idx].SetID(synthetic_sym_id++);
- sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
- if (resolver_addresses.find(symbol_stub_addr) ==
- resolver_addresses.end())
- sym[sym_idx].SetType(eSymbolTypeTrampoline);
- else
- sym[sym_idx].SetType(eSymbolTypeResolver);
- sym[sym_idx].SetIsSynthetic(true);
- sym[sym_idx].GetAddressRef() = so_addr;
- sym[sym_idx].SetByteSize(symbol_stub_byte_size);
- ++sym_idx;
- }
- } else {
- if (log)
- log->Warning("symbol stub referencing symbol table symbol "
- "%u that isn't in our minimal symbol table, "
- "fix this!!!",
- stub_sym_id);
- }
- }
- }
- }
- }
- }
- }
-
- if (!trie_entries.empty()) {
- for (const auto &e : trie_entries) {
- if (e.entry.import_name) {
- // Only add indirect symbols from the Trie entries if we didn't have
- // a N_INDR nlist entry for this already
- if (indirect_symbol_names.find(e.entry.name) ==
- indirect_symbol_names.end()) {
- // Make a synthetic symbol to describe re-exported symbol.
- if (sym_idx >= num_syms)
- sym = symtab->Resize(++num_syms);
- sym[sym_idx].SetID(synthetic_sym_id++);
- sym[sym_idx].GetMangled() = Mangled(e.entry.name);
- sym[sym_idx].SetType(eSymbolTypeReExported);
- sym[sym_idx].SetIsSynthetic(true);
- sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
- if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
- sym[sym_idx].SetReExportedSymbolSharedLibrary(
- dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
- }
- ++sym_idx;
- }
- }
- }
- }
-
- // StreamFile s(stdout, false);
- // s.Printf ("Symbol table before CalculateSymbolSizes():\n");
- // symtab->Dump(&s, NULL, eSortOrderNone);
- // Set symbol byte sizes correctly since mach-o nlist entries don't have
- // sizes
- symtab->CalculateSymbolSizes();
-
- // s.Printf ("Symbol table after CalculateSymbolSizes():\n");
- // symtab->Dump(&s, NULL, eSortOrderNone);
-
- return symtab->GetNumSymbols();
- }
- return 0;
-}
-
-void ObjectFileMachO::Dump(Stream *s) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- s->Printf("%p: ", static_cast<void *>(this));
- s->Indent();
- if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
- s->PutCString("ObjectFileMachO64");
- else
- s->PutCString("ObjectFileMachO32");
-
- ArchSpec header_arch = GetArchitecture();
-
- *s << ", file = '" << m_file
- << "', triple = " << header_arch.GetTriple().getTriple() << "\n";
-
- SectionList *sections = GetSectionList();
- if (sections)
- sections->Dump(s, NULL, true, UINT32_MAX);
-
- if (m_symtab_ap.get())
- m_symtab_ap->Dump(s, NULL, eSortOrderNone);
- }
-}
-
-bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- lldb::offset_t lc_offset,
- lldb_private::UUID &uuid) {
- uint32_t i;
- struct uuid_command load_cmd;
-
- lldb::offset_t offset = lc_offset;
- for (i = 0; i < header.ncmds; ++i) {
- const lldb::offset_t cmd_offset = offset;
- if (data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
-
- if (load_cmd.cmd == LC_UUID) {
- const uint8_t *uuid_bytes = data.PeekData(offset, 16);
-
- if (uuid_bytes) {
- // OpenCL on Mac OS X uses the same UUID for each of its object files.
- // We pretend these object files have no UUID to prevent crashing.
-
- const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
- 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
- 0xbb, 0x14, 0xf0, 0x0d};
-
- if (!memcmp(uuid_bytes, opencl_uuid, 16))
- return false;
-
- uuid = UUID::fromOptionalData(uuid_bytes, 16);
- return true;
- }
- return false;
- }
- offset = cmd_offset + load_cmd.cmdsize;
- }
- return false;
-}
-
-static llvm::StringRef GetOSName(uint32_t cmd) {
- switch (cmd) {
- case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
- return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
- case llvm::MachO::LC_VERSION_MIN_MACOSX:
- return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
- case llvm::MachO::LC_VERSION_MIN_TVOS:
- return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
- case llvm::MachO::LC_VERSION_MIN_WATCHOS:
- return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
- default:
- llvm_unreachable("unexpected LC_VERSION load command");
- }
-}
-
-namespace {
- struct OSEnv {
- llvm::StringRef os_type;
- llvm::StringRef environment;
- OSEnv(uint32_t cmd) {
- switch (cmd) {
- case PLATFORM_MACOS:
- os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
- return;
- case PLATFORM_IOS:
- os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
- return;
- case PLATFORM_TVOS:
- os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
- return;
- case PLATFORM_WATCHOS:
- os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
- return;
-// NEED_BRIDGEOS_TRIPLE case PLATFORM_BRIDGEOS:
-// NEED_BRIDGEOS_TRIPLE os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
-// NEED_BRIDGEOS_TRIPLE return;
-#if defined (PLATFORM_IOSSIMULATOR) && defined (PLATFORM_TVOSSIMULATOR) && defined (PLATFORM_WATCHOSSIMULATOR)
- case PLATFORM_IOSSIMULATOR:
- os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
- environment =
- llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
- return;
- case PLATFORM_TVOSSIMULATOR:
- os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
- environment =
- llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
- return;
- case PLATFORM_WATCHOSSIMULATOR:
- os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
- environment =
- llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
- return;
-#endif
- default: {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS |
- LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("unsupported platform in LC_BUILD_VERSION");
- }
- }
- }
- };
-
- struct MinOS {
- uint32_t major_version, minor_version, patch_version;
- MinOS(uint32_t version)
- : major_version(version >> 16),
- minor_version((version >> 8) & 0xffu),
- patch_version(version & 0xffu) {}
- };
-} // namespace
-
-ArchSpec
-ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- lldb::offset_t lc_offset) {
- ArchSpec arch;
- arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);
-
- if (arch.IsValid()) {
- llvm::Triple &triple = arch.GetTriple();
-
- // Set OS to an unspecified unknown or a "*" so it can match any OS
- triple.setOS(llvm::Triple::UnknownOS);
- triple.setOSName(llvm::StringRef());
-
- if (header.filetype == MH_PRELOAD) {
- if (header.cputype == CPU_TYPE_ARM) {
- // If this is a 32-bit arm binary, and it's a standalone binary, force
- // the Vendor to Apple so we don't accidentally pick up the generic
- // armv7 ABI at runtime. Apple's armv7 ABI always uses r7 for the
- // frame pointer register; most other armv7 ABIs use a combination of
- // r7 and r11.
- triple.setVendor(llvm::Triple::Apple);
- } else {
- // Set vendor to an unspecified unknown or a "*" so it can match any
- // vendor This is required for correct behavior of EFI debugging on
- // x86_64
- triple.setVendor(llvm::Triple::UnknownVendor);
- triple.setVendorName(llvm::StringRef());
- }
- return arch;
- } else {
- struct load_command load_cmd;
- llvm::SmallString<16> os_name;
- llvm::raw_svector_ostream os(os_name);
-
- // See if there is an LC_VERSION_MIN_* load command that can give
- // us the OS type.
- lldb::offset_t offset = lc_offset;
- for (uint32_t i = 0; i < header.ncmds; ++i) {
- const lldb::offset_t cmd_offset = offset;
- if (data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
-
- struct version_min_command version_min;
- switch (load_cmd.cmd) {
- case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
- case llvm::MachO::LC_VERSION_MIN_MACOSX:
- case llvm::MachO::LC_VERSION_MIN_TVOS:
- case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
- if (load_cmd.cmdsize != sizeof(version_min))
- break;
- if (data.ExtractBytes(cmd_offset, sizeof(version_min),
- data.GetByteOrder(), &version_min) == 0)
- break;
- MinOS min_os(version_min.version);
- os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'
- << min_os.minor_version << '.' << min_os.patch_version;
- triple.setOSName(os.str());
- return arch;
- }
- default:
- break;
- }
-
- offset = cmd_offset + load_cmd.cmdsize;
- }
-
- // See if there is an LC_BUILD_VERSION load command that can give
- // us the OS type.
-
- offset = lc_offset;
- for (uint32_t i = 0; i < header.ncmds; ++i) {
- const lldb::offset_t cmd_offset = offset;
- if (data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
- do {
- if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
- struct build_version_command build_version;
- if (load_cmd.cmdsize < sizeof(build_version)) {
- // Malformed load command.
- break;
- }
- if (data.ExtractBytes(cmd_offset, sizeof(build_version),
- data.GetByteOrder(), &build_version) == 0)
- break;
- MinOS min_os(build_version.minos);
- OSEnv os_env(build_version.platform);
- if (os_env.os_type.empty())
- break;
- os << os_env.os_type << min_os.major_version << '.'
- << min_os.minor_version << '.' << min_os.patch_version;
- triple.setOSName(os.str());
- if (!os_env.environment.empty())
- triple.setEnvironmentName(os_env.environment);
- return arch;
- }
- } while (0);
- offset = cmd_offset + load_cmd.cmdsize;
- }
-
- if (header.filetype != MH_KEXT_BUNDLE) {
- // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
- // so lets not say our Vendor is Apple, leave it as an unspecified
- // unknown
- triple.setVendor(llvm::Triple::UnknownVendor);
- triple.setVendorName(llvm::StringRef());
- }
- }
- }
- return arch;
-}
-
-bool ObjectFileMachO::GetUUID(lldb_private::UUID *uuid) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- return GetUUID(m_header, m_data, offset, *uuid);
- }
- return false;
-}
-
-uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
- uint32_t count = 0;
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- struct load_command load_cmd;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- std::vector<std::string> rpath_paths;
- std::vector<std::string> rpath_relative_paths;
- std::vector<std::string> at_exec_relative_paths;
- uint32_t i;
- for (i = 0; i < m_header.ncmds; ++i) {
- const uint32_t cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
-
- switch (load_cmd.cmd) {
- case LC_RPATH:
- case LC_LOAD_DYLIB:
- case LC_LOAD_WEAK_DYLIB:
- case LC_REEXPORT_DYLIB:
- case LC_LOAD_DYLINKER:
- case LC_LOADFVMLIB:
- case LC_LOAD_UPWARD_DYLIB: {
- uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
- const char *path = m_data.PeekCStr(name_offset);
- if (path) {
- if (load_cmd.cmd == LC_RPATH)
- rpath_paths.push_back(path);
- else {
- if (path[0] == '@') {
- if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
- rpath_relative_paths.push_back(path + strlen("@rpath"));
- else if (strncmp(path, "@executable_path",
- strlen("@executable_path")) == 0)
- at_exec_relative_paths.push_back(path
- + strlen("@executable_path"));
- } else {
- FileSpec file_spec(path);
- if (files.AppendIfUnique(file_spec))
- count++;
- }
- }
- }
- } break;
-
- default:
- break;
- }
- offset = cmd_offset + load_cmd.cmdsize;
- }
-
- FileSpec this_file_spec(m_file);
- FileSystem::Instance().Resolve(this_file_spec);
-
- if (!rpath_paths.empty()) {
- // Fixup all LC_RPATH values to be absolute paths
- std::string loader_path("@loader_path");
- std::string executable_path("@executable_path");
- for (auto &rpath : rpath_paths) {
- if (rpath.find(loader_path) == 0) {
- rpath.erase(0, loader_path.size());
- rpath.insert(0, this_file_spec.GetDirectory().GetCString());
- } else if (rpath.find(executable_path) == 0) {
- rpath.erase(0, executable_path.size());
- rpath.insert(0, this_file_spec.GetDirectory().GetCString());
- }
- }
-
- for (const auto &rpath_relative_path : rpath_relative_paths) {
- for (const auto &rpath : rpath_paths) {
- std::string path = rpath;
- path += rpath_relative_path;
- // It is OK to resolve this path because we must find a file on disk
- // for us to accept it anyway if it is rpath relative.
- FileSpec file_spec(path);
- FileSystem::Instance().Resolve(file_spec);
- if (FileSystem::Instance().Exists(file_spec) &&
- files.AppendIfUnique(file_spec)) {
- count++;
- break;
- }
- }
- }
- }
-
- // We may have @executable_paths but no RPATHS. Figure those out here.
- // Only do this if this object file is the executable. We have no way to
- // get back to the actual executable otherwise, so we won't get the right
- // path.
- if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {
- FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();
- for (const auto &at_exec_relative_path : at_exec_relative_paths) {
- FileSpec file_spec =
- exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
- if (FileSystem::Instance().Exists(file_spec) &&
- files.AppendIfUnique(file_spec))
- count++;
- }
- }
- }
- return count;
-}
-
-lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
- // If the object file is not an executable it can't hold the entry point.
- // m_entry_point_address is initialized to an invalid address, so we can just
- // return that. If m_entry_point_address is valid it means we've found it
- // already, so return the cached value.
-
- if (!IsExecutable() || m_entry_point_address.IsValid())
- return m_entry_point_address;
-
- // Otherwise, look for the UnixThread or Thread command. The data for the
- // Thread command is given in /usr/include/mach-o.h, but it is basically:
- //
- // uint32_t flavor - this is the flavor argument you would pass to
- // thread_get_state
- // uint32_t count - this is the count of longs in the thread state data
- // struct XXX_thread_state state - this is the structure from
- // <machine/thread_status.h> corresponding to the flavor.
- // <repeat this trio>
- //
- // So we just keep reading the various register flavors till we find the GPR
- // one, then read the PC out of there.
- // FIXME: We will need to have a "RegisterContext data provider" class at some
- // point that can get all the registers
- // out of data in this form & attach them to a given thread. That should
- // underlie the MacOS X User process plugin, and we'll also need it for the
- // MacOS X Core File process plugin. When we have that we can also use it
- // here.
- //
- // For now we hard-code the offsets and flavors we need:
- //
- //
-
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- struct load_command load_cmd;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t i;
- lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
- bool done = false;
-
- for (i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
-
- switch (load_cmd.cmd) {
- case LC_UNIXTHREAD:
- case LC_THREAD: {
- while (offset < cmd_offset + load_cmd.cmdsize) {
- uint32_t flavor = m_data.GetU32(&offset);
- uint32_t count = m_data.GetU32(&offset);
- if (count == 0) {
- // We've gotten off somehow, log and exit;
- return m_entry_point_address;
- }
-
- switch (m_header.cputype) {
- case llvm::MachO::CPU_TYPE_ARM:
- if (flavor == 1 ||
- flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from
- // mach/arm/thread_status.h
- {
- offset += 60; // This is the offset of pc in the GPR thread state
- // data structure.
- start_address = m_data.GetU32(&offset);
- done = true;
- }
- break;
- case llvm::MachO::CPU_TYPE_ARM64:
- if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
- {
- offset += 256; // This is the offset of pc in the GPR thread state
- // data structure.
- start_address = m_data.GetU64(&offset);
- done = true;
- }
- break;
- case llvm::MachO::CPU_TYPE_I386:
- if (flavor ==
- 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
- {
- offset += 40; // This is the offset of eip in the GPR thread state
- // data structure.
- start_address = m_data.GetU32(&offset);
- done = true;
- }
- break;
- case llvm::MachO::CPU_TYPE_X86_64:
- if (flavor ==
- 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
- {
- offset += 16 * 8; // This is the offset of rip in the GPR thread
- // state data structure.
- start_address = m_data.GetU64(&offset);
- done = true;
- }
- break;
- default:
- return m_entry_point_address;
- }
- // Haven't found the GPR flavor yet, skip over the data for this
- // flavor:
- if (done)
- break;
- offset += count * 4;
- }
- } break;
- case LC_MAIN: {
- ConstString text_segment_name("__TEXT");
- uint64_t entryoffset = m_data.GetU64(&offset);
- SectionSP text_segment_sp =
- GetSectionList()->FindSectionByName(text_segment_name);
- if (text_segment_sp) {
- done = true;
- start_address = text_segment_sp->GetFileAddress() + entryoffset;
- }
- } break;
-
- default:
- break;
- }
- if (done)
- break;
-
- // Go to the next load command:
- offset = cmd_offset + load_cmd.cmdsize;
- }
-
- if (start_address != LLDB_INVALID_ADDRESS) {
- // We got the start address from the load commands, so now resolve that
- // address in the sections of this ObjectFile:
- if (!m_entry_point_address.ResolveAddressUsingFileSections(
- start_address, GetSectionList())) {
- m_entry_point_address.Clear();
- }
- } else {
- // We couldn't read the UnixThread load command - maybe it wasn't there.
- // As a fallback look for the "start" symbol in the main executable.
-
- ModuleSP module_sp(GetModule());
-
- if (module_sp) {
- SymbolContextList contexts;
- SymbolContext context;
- if (module_sp->FindSymbolsWithNameAndType(ConstString("start"),
- eSymbolTypeCode, contexts)) {
- if (contexts.GetContextAtIndex(0, context))
- m_entry_point_address = context.symbol->GetAddress();
- }
- }
- }
- }
-
- return m_entry_point_address;
-}
-
-lldb_private::Address ObjectFileMachO::GetBaseAddress() {
- lldb_private::Address header_addr;
- SectionList *section_list = GetSectionList();
- if (section_list) {
- SectionSP text_segment_sp(
- section_list->FindSectionByName(GetSegmentNameTEXT()));
- if (text_segment_sp) {
- header_addr.SetSection(text_segment_sp);
- header_addr.SetOffset(0);
- }
- }
- return header_addr;
-}
-
-uint32_t ObjectFileMachO::GetNumThreadContexts() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (!m_thread_context_offsets_valid) {
- m_thread_context_offsets_valid = true;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- FileRangeArray::Entry file_range;
- thread_command thread_cmd;
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const uint32_t cmd_offset = offset;
- if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
- break;
-
- if (thread_cmd.cmd == LC_THREAD) {
- file_range.SetRangeBase(offset);
- file_range.SetByteSize(thread_cmd.cmdsize - 8);
- m_thread_context_offsets.Append(file_range);
- }
- offset = cmd_offset + thread_cmd.cmdsize;
- }
- }
- }
- return m_thread_context_offsets.GetSize();
-}
-
-std::string ObjectFileMachO::GetIdentifierString() {
- std::string result;
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-
- // First, look over the load commands for an LC_NOTE load command with
- // data_owner string "kern ver str" & use that if found.
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const uint32_t cmd_offset = offset;
- load_command lc;
- if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
- break;
- if (lc.cmd == LC_NOTE)
- {
- char data_owner[17];
- m_data.CopyData (offset, 16, data_owner);
- data_owner[16] = '\0';
- offset += 16;
- uint64_t fileoff = m_data.GetU64_unchecked (&offset);
- uint64_t size = m_data.GetU64_unchecked (&offset);
-
- // "kern ver str" has a uint32_t version and then a nul terminated
- // c-string.
- if (strcmp ("kern ver str", data_owner) == 0)
- {
- offset = fileoff;
- uint32_t version;
- if (m_data.GetU32 (&offset, &version, 1) != nullptr)
- {
- if (version == 1)
- {
- uint32_t strsize = size - sizeof (uint32_t);
- char *buf = (char*) malloc (strsize);
- if (buf)
- {
- m_data.CopyData (offset, strsize, buf);
- buf[strsize - 1] = '\0';
- result = buf;
- if (buf)
- free (buf);
- return result;
- }
- }
- }
- }
- }
- offset = cmd_offset + lc.cmdsize;
- }
-
- // Second, make a pass over the load commands looking for an obsolete
- // LC_IDENT load command.
- offset = MachHeaderSizeFromMagic(m_header.magic);
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const uint32_t cmd_offset = offset;
- struct ident_command ident_command;
- if (m_data.GetU32(&offset, &ident_command, 2) == NULL)
- break;
- if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
- char *buf = (char *) malloc (ident_command.cmdsize);
- if (buf != nullptr
- && m_data.CopyData (offset, ident_command.cmdsize, buf) == ident_command.cmdsize) {
- buf[ident_command.cmdsize - 1] = '\0';
- result = buf;
- }
- if (buf)
- free (buf);
- }
- offset = cmd_offset + ident_command.cmdsize;
- }
-
- }
- return result;
-}
-
-bool ObjectFileMachO::GetCorefileMainBinaryInfo (addr_t &address, UUID &uuid) {
- address = LLDB_INVALID_ADDRESS;
- uuid.Clear();
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const uint32_t cmd_offset = offset;
- load_command lc;
- if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
- break;
- if (lc.cmd == LC_NOTE)
- {
- char data_owner[17];
- memset (data_owner, 0, sizeof (data_owner));
- m_data.CopyData (offset, 16, data_owner);
- offset += 16;
- uint64_t fileoff = m_data.GetU64_unchecked (&offset);
- uint64_t size = m_data.GetU64_unchecked (&offset);
-
- // "main bin spec" (main binary specification) data payload is
- // formatted:
- // uint32_t version [currently 1]
- // uint32_t type [0 == unspecified, 1 == kernel, 2 == user process]
- // uint64_t address [ UINT64_MAX if address not specified ]
- // uuid_t uuid [ all zero's if uuid not specified ]
- // uint32_t log2_pagesize [ process page size in log base 2, e.g. 4k pages are 12. 0 for unspecified ]
-
- if (strcmp ("main bin spec", data_owner) == 0 && size >= 32)
- {
- offset = fileoff;
- uint32_t version;
- if (m_data.GetU32 (&offset, &version, 1) != nullptr && version == 1)
- {
- uint32_t type = 0;
- uuid_t raw_uuid;
- memset (raw_uuid, 0, sizeof (uuid_t));
-
- if (m_data.GetU32(&offset, &type, 1) &&
- m_data.GetU64(&offset, &address, 1) &&
- m_data.CopyData(offset, sizeof(uuid_t), raw_uuid) != 0) {
- uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t));
- return true;
- }
- }
- }
- }
- offset = cmd_offset + lc.cmdsize;
- }
- }
- return false;
-}
-
-lldb::RegisterContextSP
-ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
- lldb_private::Thread &thread) {
- lldb::RegisterContextSP reg_ctx_sp;
-
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (!m_thread_context_offsets_valid)
- GetNumThreadContexts();
-
- const FileRangeArray::Entry *thread_context_file_range =
- m_thread_context_offsets.GetEntryAtIndex(idx);
- if (thread_context_file_range) {
-
- DataExtractor data(m_data, thread_context_file_range->GetRangeBase(),
- thread_context_file_range->GetByteSize());
-
- switch (m_header.cputype) {
- case llvm::MachO::CPU_TYPE_ARM64:
- reg_ctx_sp.reset(new RegisterContextDarwin_arm64_Mach(thread, data));
- break;
-
- case llvm::MachO::CPU_TYPE_ARM:
- reg_ctx_sp.reset(new RegisterContextDarwin_arm_Mach(thread, data));
- break;
-
- case llvm::MachO::CPU_TYPE_I386:
- reg_ctx_sp.reset(new RegisterContextDarwin_i386_Mach(thread, data));
- break;
-
- case llvm::MachO::CPU_TYPE_X86_64:
- reg_ctx_sp.reset(new RegisterContextDarwin_x86_64_Mach(thread, data));
- break;
- }
- }
- }
- return reg_ctx_sp;
-}
-
-ObjectFile::Type ObjectFileMachO::CalculateType() {
- switch (m_header.filetype) {
- case MH_OBJECT: // 0x1u
- if (GetAddressByteSize() == 4) {
- // 32 bit kexts are just object files, but they do have a valid
- // UUID load command.
- UUID uuid;
- if (GetUUID(&uuid)) {
- // this checking for the UUID load command is not enough we could
- // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
- // this is required of kexts
- if (m_strata == eStrataInvalid)
- m_strata = eStrataKernel;
- return eTypeSharedLibrary;
- }
- }
- return eTypeObjectFile;
-
- case MH_EXECUTE:
- return eTypeExecutable; // 0x2u
- case MH_FVMLIB:
- return eTypeSharedLibrary; // 0x3u
- case MH_CORE:
- return eTypeCoreFile; // 0x4u
- case MH_PRELOAD:
- return eTypeSharedLibrary; // 0x5u
- case MH_DYLIB:
- return eTypeSharedLibrary; // 0x6u
- case MH_DYLINKER:
- return eTypeDynamicLinker; // 0x7u
- case MH_BUNDLE:
- return eTypeSharedLibrary; // 0x8u
- case MH_DYLIB_STUB:
- return eTypeStubLibrary; // 0x9u
- case MH_DSYM:
- return eTypeDebugInfo; // 0xAu
- case MH_KEXT_BUNDLE:
- return eTypeSharedLibrary; // 0xBu
- default:
- break;
- }
- return eTypeUnknown;
-}
-
-ObjectFile::Strata ObjectFileMachO::CalculateStrata() {
- switch (m_header.filetype) {
- case MH_OBJECT: // 0x1u
- {
- // 32 bit kexts are just object files, but they do have a valid
- // UUID load command.
- UUID uuid;
- if (GetUUID(&uuid)) {
- // this checking for the UUID load command is not enough we could
- // eventually look for the symbol named "OSKextGetCurrentIdentifier" as
- // this is required of kexts
- if (m_type == eTypeInvalid)
- m_type = eTypeSharedLibrary;
-
- return eStrataKernel;
- }
- }
- return eStrataUnknown;
-
- case MH_EXECUTE: // 0x2u
- // Check for the MH_DYLDLINK bit in the flags
- if (m_header.flags & MH_DYLDLINK) {
- return eStrataUser;
- } else {
- SectionList *section_list = GetSectionList();
- if (section_list) {
- static ConstString g_kld_section_name("__KLD");
- if (section_list->FindSectionByName(g_kld_section_name))
- return eStrataKernel;
- }
- }
- return eStrataRawImage;
-
- case MH_FVMLIB:
- return eStrataUser; // 0x3u
- case MH_CORE:
- return eStrataUnknown; // 0x4u
- case MH_PRELOAD:
- return eStrataRawImage; // 0x5u
- case MH_DYLIB:
- return eStrataUser; // 0x6u
- case MH_DYLINKER:
- return eStrataUser; // 0x7u
- case MH_BUNDLE:
- return eStrataUser; // 0x8u
- case MH_DYLIB_STUB:
- return eStrataUser; // 0x9u
- case MH_DSYM:
- return eStrataUnknown; // 0xAu
- case MH_KEXT_BUNDLE:
- return eStrataKernel; // 0xBu
- default:
- break;
- }
- return eStrataUnknown;
-}
-
-llvm::VersionTuple ObjectFileMachO::GetVersion() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- struct dylib_command load_cmd;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t version_cmd = 0;
- uint64_t version = 0;
- uint32_t i;
- for (i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
-
- if (load_cmd.cmd == LC_ID_DYLIB) {
- if (version_cmd == 0) {
- version_cmd = load_cmd.cmd;
- if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
- break;
- version = load_cmd.dylib.current_version;
- }
- break; // Break for now unless there is another more complete version
- // number load command in the future.
- }
- offset = cmd_offset + load_cmd.cmdsize;
- }
-
- if (version_cmd == LC_ID_DYLIB) {
- unsigned major = (version & 0xFFFF0000ull) >> 16;
- unsigned minor = (version & 0x0000FF00ull) >> 8;
- unsigned subminor = (version & 0x000000FFull);
- return llvm::VersionTuple(major, minor, subminor);
- }
- }
- return llvm::VersionTuple();
-}
-
-ArchSpec ObjectFileMachO::GetArchitecture() {
- ModuleSP module_sp(GetModule());
- ArchSpec arch;
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-
- return GetArchitecture(m_header, m_data,
- MachHeaderSizeFromMagic(m_header.magic));
- }
- return arch;
-}
-
-void ObjectFileMachO::GetProcessSharedCacheUUID(Process *process, addr_t &base_addr, UUID &uuid) {
- uuid.Clear();
- base_addr = LLDB_INVALID_ADDRESS;
- if (process && process->GetDynamicLoader()) {
- DynamicLoader *dl = process->GetDynamicLoader();
- LazyBool using_shared_cache;
- LazyBool private_shared_cache;
- dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
- private_shared_cache);
- }
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("inferior process shared cache has a UUID of %s, base address 0x%" PRIx64 , uuid.GetAsString().c_str(), base_addr);
-}
-
-// From dyld SPI header dyld_process_info.h
-typedef void *dyld_process_info;
-struct lldb_copy__dyld_process_cache_info {
- uuid_t cacheUUID; // UUID of cache used by process
- uint64_t cacheBaseAddress; // load address of dyld shared cache
- bool noCache; // process is running without a dyld cache
- bool privateCache; // process is using a private copy of its dyld cache
-};
-
-// #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with llvm
-// enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile errors.
-// So we need to use the actual underlying types of task_t and kern_return_t
-// below.
-extern "C" unsigned int /*task_t*/ mach_task_self();
-
-void ObjectFileMachO::GetLLDBSharedCacheUUID(addr_t &base_addr, UUID &uuid) {
- uuid.Clear();
- base_addr = LLDB_INVALID_ADDRESS;
-
-#if defined(__APPLE__) && \
- (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
- uint8_t *(*dyld_get_all_image_infos)(void);
- dyld_get_all_image_infos =
- (uint8_t * (*)())dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");
- if (dyld_get_all_image_infos) {
- uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
- if (dyld_all_image_infos_address) {
- uint32_t *version = (uint32_t *)
- dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
- if (*version >= 13) {
- uuid_t *sharedCacheUUID_address = 0;
- int wordsize = sizeof(uint8_t *);
- if (wordsize == 8) {
- sharedCacheUUID_address =
- (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
- 160); // sharedCacheUUID <mach-o/dyld_images.h>
- if (*version >= 15)
- base_addr = *(uint64_t *) ((uint8_t *) dyld_all_image_infos_address
- + 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
- } else {
- sharedCacheUUID_address =
- (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
- 84); // sharedCacheUUID <mach-o/dyld_images.h>
- if (*version >= 15) {
- base_addr = 0;
- base_addr = *(uint32_t *) ((uint8_t *) dyld_all_image_infos_address
- + 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
- }
- }
- uuid = UUID::fromOptionalData(sharedCacheUUID_address, sizeof(uuid_t));
- }
- }
- } else {
- // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
- dyld_process_info (*dyld_process_info_create)(unsigned int /* task_t */ task, uint64_t timestamp, unsigned int /*kern_return_t*/ *kernelError);
- void (*dyld_process_info_get_cache)(void *info, void *cacheInfo);
- void (*dyld_process_info_release)(dyld_process_info info);
-
- dyld_process_info_create = (void *(*)(unsigned int /* task_t */, uint64_t, unsigned int /*kern_return_t*/ *))
- dlsym (RTLD_DEFAULT, "_dyld_process_info_create");
- dyld_process_info_get_cache = (void (*)(void *, void *))
- dlsym (RTLD_DEFAULT, "_dyld_process_info_get_cache");
- dyld_process_info_release = (void (*)(void *))
- dlsym (RTLD_DEFAULT, "_dyld_process_info_release");
-
- if (dyld_process_info_create && dyld_process_info_get_cache) {
- unsigned int /*kern_return_t */ kern_ret;
- dyld_process_info process_info = dyld_process_info_create(::mach_task_self(), 0, &kern_ret);
- if (process_info) {
- struct lldb_copy__dyld_process_cache_info sc_info;
- memset (&sc_info, 0, sizeof (struct lldb_copy__dyld_process_cache_info));
- dyld_process_info_get_cache (process_info, &sc_info);
- if (sc_info.cacheBaseAddress != 0) {
- base_addr = sc_info.cacheBaseAddress;
- uuid = UUID::fromOptionalData(sc_info.cacheUUID, sizeof(uuid_t));
- }
- dyld_process_info_release (process_info);
- }
- }
- }
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_PROCESS));
- if (log && uuid.IsValid())
- log->Printf("lldb's in-memory shared cache has a UUID of %s base address of 0x%" PRIx64, uuid.GetAsString().c_str(), base_addr);
-#endif
-}
-
-llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {
- if (!m_min_os_version) {
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- for (uint32_t i = 0; i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
-
- version_min_command lc;
- if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
- break;
- if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
- lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
- lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
- lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
- if (m_data.GetU32(&offset, &lc.version,
- (sizeof(lc) / sizeof(uint32_t)) - 2)) {
- const uint32_t xxxx = lc.version >> 16;
- const uint32_t yy = (lc.version >> 8) & 0xffu;
- const uint32_t zz = lc.version & 0xffu;
- if (xxxx) {
- m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
- break;
- }
- }
- } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
- // struct build_version_command {
- // uint32_t cmd; /* LC_BUILD_VERSION */
- // uint32_t cmdsize; /* sizeof(struct build_version_command) plus */
- // /* ntools * sizeof(struct build_tool_version) */
- // uint32_t platform; /* platform */
- // uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
- // uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
- // uint32_t ntools; /* number of tool entries following this */
- // };
-
- offset += 4; // skip platform
- uint32_t minos = m_data.GetU32(&offset);
-
- const uint32_t xxxx = minos >> 16;
- const uint32_t yy = (minos >> 8) & 0xffu;
- const uint32_t zz = minos & 0xffu;
- if (xxxx) {
- m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
- break;
- }
- }
-
- offset = load_cmd_offset + lc.cmdsize;
- }
-
- if (!m_min_os_version) {
- // Set version to an empty value so we don't keep trying to
- m_min_os_version = llvm::VersionTuple();
- }
- }
-
- return *m_min_os_version;
-}
-
-uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
- uint32_t num_versions) {
- if (m_sdk_versions.empty()) {
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- bool success = false;
- for (uint32_t i = 0; !success && i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
-
- version_min_command lc;
- if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
- break;
- if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
- lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
- lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
- lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
- if (m_data.GetU32(&offset, &lc.version,
- (sizeof(lc) / sizeof(uint32_t)) - 2)) {
- const uint32_t xxxx = lc.sdk >> 16;
- const uint32_t yy = (lc.sdk >> 8) & 0xffu;
- const uint32_t zz = lc.sdk & 0xffu;
- if (xxxx) {
- m_sdk_versions.push_back(xxxx);
- m_sdk_versions.push_back(yy);
- m_sdk_versions.push_back(zz);
- success = true;
- } else {
- GetModule()->ReportWarning(
- "minimum OS version load command with invalid (0) version found.");
- }
- }
- }
- offset = load_cmd_offset + lc.cmdsize;
- }
-
- if (!success) {
- offset = MachHeaderSizeFromMagic(m_header.magic);
- for (uint32_t i = 0; !success && i < m_header.ncmds; ++i) {
- const lldb::offset_t load_cmd_offset = offset;
-
- version_min_command lc;
- if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
- break;
- if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
- // struct build_version_command {
- // uint32_t cmd; /* LC_BUILD_VERSION */
- // uint32_t cmdsize; /* sizeof(struct
- // build_version_command) plus */
- // /* ntools * sizeof(struct
- // build_tool_version) */
- // uint32_t platform; /* platform */
- // uint32_t minos; /* X.Y.Z is encoded in nibbles
- // xxxx.yy.zz */ uint32_t sdk; /* X.Y.Z is encoded
- // in nibbles xxxx.yy.zz */ uint32_t ntools; /* number
- // of tool entries following this */
- // };
-
- offset += 4; // skip platform
- uint32_t minos = m_data.GetU32(&offset);
-
- const uint32_t xxxx = minos >> 16;
- const uint32_t yy = (minos >> 8) & 0xffu;
- const uint32_t zz = minos & 0xffu;
- if (xxxx) {
- m_sdk_versions.push_back(xxxx);
- m_sdk_versions.push_back(yy);
- m_sdk_versions.push_back(zz);
- success = true;
- }
- }
- offset = load_cmd_offset + lc.cmdsize;
- }
- }
-
- if (!success) {
- // Push an invalid value so we don't try to find
- // the version # again on the next call to this
- // method.
- m_sdk_versions.push_back(UINT32_MAX);
- }
- }
-
- // Legitimate version numbers will have 3 entries pushed
- // on to m_sdk_versions. If we only have one value, it's
- // the sentinel value indicating that this object file
- // does not have a valid minimum os version #.
- if (m_sdk_versions.size() > 1) {
- if (versions != NULL && num_versions > 0) {
- for (size_t i = 0; i < num_versions; ++i) {
- if (i < m_sdk_versions.size())
- versions[i] = m_sdk_versions[i];
- else
- versions[i] = 0;
- }
- }
- return m_sdk_versions.size();
- }
- // Call the superclasses version that will empty out the data
- return ObjectFile::GetSDKVersion(versions, num_versions);
-}
-
-bool ObjectFileMachO::GetIsDynamicLinkEditor() {
- return m_header.filetype == llvm::MachO::MH_DYLINKER;
-}
-
-bool ObjectFileMachO::AllowAssemblyEmulationUnwindPlans() {
- return m_allow_assembly_emulation_unwind_plans;
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString ObjectFileMachO::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ObjectFileMachO::GetPluginVersion() { return 1; }
-
-Section *ObjectFileMachO::GetMachHeaderSection() {
- // Find the first address of the mach header which is the first non-zero file
- // sized section whose file offset is zero. This is the base file address of
- // the mach-o file which can be subtracted from the vmaddr of the other
- // segments found in memory and added to the load address
- ModuleSP module_sp = GetModule();
- if (!module_sp)
- return nullptr;
- SectionList *section_list = GetSectionList();
- if (!section_list)
- return nullptr;
- const size_t num_sections = section_list->GetSize();
- for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- Section *section = section_list->GetSectionAtIndex(sect_idx).get();
- if (section->GetFileOffset() == 0 && SectionIsLoadable(section))
- return section;
- }
- return nullptr;
-}
-
-bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
- if (!section)
- return false;
- const bool is_dsym = (m_header.filetype == MH_DSYM);
- if (section->GetFileSize() == 0 && !is_dsym)
- return false;
- if (section->IsThreadSpecific())
- return false;
- if (GetModule().get() != section->GetModule().get())
- return false;
- // Be careful with __LINKEDIT and __DWARF segments
- if (section->GetName() == GetSegmentNameLINKEDIT() ||
- section->GetName() == GetSegmentNameDWARF()) {
- // Only map __LINKEDIT and __DWARF if we have an in memory image and
- // this isn't a kernel binary like a kext or mach_kernel.
- const bool is_memory_image = (bool)m_process_wp.lock();
- const Strata strata = GetStrata();
- if (is_memory_image == false || strata == eStrataKernel)
- return false;
- }
- return true;
-}
-
-lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
- lldb::addr_t header_load_address, const Section *header_section,
- const Section *section) {
- ModuleSP module_sp = GetModule();
- if (module_sp && header_section && section &&
- header_load_address != LLDB_INVALID_ADDRESS) {
- lldb::addr_t file_addr = header_section->GetFileAddress();
- if (file_addr != LLDB_INVALID_ADDRESS && SectionIsLoadable(section))
- return section->GetFileAddress() - file_addr + header_load_address;
- }
- return LLDB_INVALID_ADDRESS;
-}
-
-bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
- bool value_is_offset) {
- ModuleSP module_sp = GetModule();
- if (module_sp) {
- size_t num_loaded_sections = 0;
- SectionList *section_list = GetSectionList();
- if (section_list) {
- const size_t num_sections = section_list->GetSize();
-
- if (value_is_offset) {
- // "value" is an offset to apply to each top level segment
- for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find all of the
- // sections that size on disk (to avoid __PAGEZERO) and load them
- SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
- if (SectionIsLoadable(section_sp.get()))
- if (target.GetSectionLoadList().SetSectionLoadAddress(
- section_sp, section_sp->GetFileAddress() + value))
- ++num_loaded_sections;
- }
- } else {
- // "value" is the new base address of the mach_header, adjust each
- // section accordingly
-
- Section *mach_header_section = GetMachHeaderSection();
- if (mach_header_section) {
- for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
-
- lldb::addr_t section_load_addr =
- CalculateSectionLoadAddressForMemoryImage(
- value, mach_header_section, section_sp.get());
- if (section_load_addr != LLDB_INVALID_ADDRESS) {
- if (target.GetSectionLoadList().SetSectionLoadAddress(
- section_sp, section_load_addr))
- ++num_loaded_sections;
- }
- }
- }
- }
- }
- return num_loaded_sections > 0;
- }
- return false;
-}
-
-bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
- const FileSpec &outfile, Status &error) {
- if (process_sp) {
- Target &target = process_sp->GetTarget();
- const ArchSpec target_arch = target.GetArchitecture();
- const llvm::Triple &target_triple = target_arch.GetTriple();
- if (target_triple.getVendor() == llvm::Triple::Apple &&
- (target_triple.getOS() == llvm::Triple::MacOSX ||
- target_triple.getOS() == llvm::Triple::IOS ||
- target_triple.getOS() == llvm::Triple::WatchOS ||
- target_triple.getOS() == llvm::Triple::TvOS)) {
- // NEED_BRIDGEOS_TRIPLE target_triple.getOS() == llvm::Triple::BridgeOS)) {
- bool make_core = false;
- switch (target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- make_core = true;
- break;
- default:
- error.SetErrorStringWithFormat("unsupported core architecture: %s",
- target_triple.str().c_str());
- break;
- }
-
- if (make_core) {
- std::vector<segment_command_64> segment_load_commands;
- // uint32_t range_info_idx = 0;
- MemoryRegionInfo range_info;
- Status range_error = process_sp->GetMemoryRegionInfo(0, range_info);
- const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
- const ByteOrder byte_order = target_arch.GetByteOrder();
- if (range_error.Success()) {
- while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS) {
- const addr_t addr = range_info.GetRange().GetRangeBase();
- const addr_t size = range_info.GetRange().GetByteSize();
-
- if (size == 0)
- break;
-
- // Calculate correct protections
- uint32_t prot = 0;
- if (range_info.GetReadable() == MemoryRegionInfo::eYes)
- prot |= VM_PROT_READ;
- if (range_info.GetWritable() == MemoryRegionInfo::eYes)
- prot |= VM_PROT_WRITE;
- if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
- prot |= VM_PROT_EXECUTE;
-
- // printf ("[%3u] [0x%16.16" PRIx64 " -
- // 0x%16.16" PRIx64 ") %c%c%c\n",
- // range_info_idx,
- // addr,
- // size,
- // (prot & VM_PROT_READ ) ? 'r' :
- // '-',
- // (prot & VM_PROT_WRITE ) ? 'w' :
- // '-',
- // (prot & VM_PROT_EXECUTE) ? 'x' :
- // '-');
-
- if (prot != 0) {
- uint32_t cmd_type = LC_SEGMENT_64;
- uint32_t segment_size = sizeof(segment_command_64);
- if (addr_byte_size == 4) {
- cmd_type = LC_SEGMENT;
- segment_size = sizeof(segment_command);
- }
- segment_command_64 segment = {
- cmd_type, // uint32_t cmd;
- segment_size, // uint32_t cmdsize;
- {0}, // char segname[16];
- addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
- size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
- 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
- size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
- prot, // uint32_t maxprot;
- prot, // uint32_t initprot;
- 0, // uint32_t nsects;
- 0}; // uint32_t flags;
- segment_load_commands.push_back(segment);
- } else {
- // No protections and a size of 1 used to be returned from old
- // debugservers when we asked about a region that was past the
- // last memory region and it indicates the end...
- if (size == 1)
- break;
- }
-
- range_error = process_sp->GetMemoryRegionInfo(
- range_info.GetRange().GetRangeEnd(), range_info);
- if (range_error.Fail())
- break;
- }
-
- StreamString buffer(Stream::eBinary, addr_byte_size, byte_order);
-
- mach_header_64 mach_header;
- if (addr_byte_size == 8) {
- mach_header.magic = MH_MAGIC_64;
- } else {
- mach_header.magic = MH_MAGIC;
- }
- mach_header.cputype = target_arch.GetMachOCPUType();
- mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
- mach_header.filetype = MH_CORE;
- mach_header.ncmds = segment_load_commands.size();
- mach_header.flags = 0;
- mach_header.reserved = 0;
- ThreadList &thread_list = process_sp->GetThreadList();
- const uint32_t num_threads = thread_list.GetSize();
-
- // Make an array of LC_THREAD data items. Each one contains the
- // contents of the LC_THREAD load command. The data doesn't contain
- // the load command + load command size, we will add the load command
- // and load command size as we emit the data.
- std::vector<StreamString> LC_THREAD_datas(num_threads);
- for (auto &LC_THREAD_data : LC_THREAD_datas) {
- LC_THREAD_data.GetFlags().Set(Stream::eBinary);
- LC_THREAD_data.SetAddressByteSize(addr_byte_size);
- LC_THREAD_data.SetByteOrder(byte_order);
- }
- for (uint32_t thread_idx = 0; thread_idx < num_threads;
- ++thread_idx) {
- ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
- if (thread_sp) {
- switch (mach_header.cputype) {
- case llvm::MachO::CPU_TYPE_ARM64:
- RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
-
- case llvm::MachO::CPU_TYPE_ARM:
- RegisterContextDarwin_arm_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
-
- case llvm::MachO::CPU_TYPE_I386:
- RegisterContextDarwin_i386_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
-
- case llvm::MachO::CPU_TYPE_X86_64:
- RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
- }
- }
- }
-
- // The size of the load command is the size of the segments...
- if (addr_byte_size == 8) {
- mach_header.sizeofcmds = segment_load_commands.size() *
- sizeof(struct segment_command_64);
- } else {
- mach_header.sizeofcmds =
- segment_load_commands.size() * sizeof(struct segment_command);
- }
-
- // and the size of all LC_THREAD load command
- for (const auto &LC_THREAD_data : LC_THREAD_datas) {
- ++mach_header.ncmds;
- mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
- }
-
- printf("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x "
- "0x%8.8x 0x%8.8x\n",
- mach_header.magic, mach_header.cputype, mach_header.cpusubtype,
- mach_header.filetype, mach_header.ncmds,
- mach_header.sizeofcmds, mach_header.flags,
- mach_header.reserved);
-
- // Write the mach header
- buffer.PutHex32(mach_header.magic);
- buffer.PutHex32(mach_header.cputype);
- buffer.PutHex32(mach_header.cpusubtype);
- buffer.PutHex32(mach_header.filetype);
- buffer.PutHex32(mach_header.ncmds);
- buffer.PutHex32(mach_header.sizeofcmds);
- buffer.PutHex32(mach_header.flags);
- if (addr_byte_size == 8) {
- buffer.PutHex32(mach_header.reserved);
- }
-
- // Skip the mach header and all load commands and align to the next
- // 0x1000 byte boundary
- addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
- if (file_offset & 0x00000fff) {
- file_offset += 0x00001000ull;
- file_offset &= (~0x00001000ull + 1);
- }
-
- for (auto &segment : segment_load_commands) {
- segment.fileoff = file_offset;
- file_offset += segment.filesize;
- }
-
- // Write out all of the LC_THREAD load commands
- for (const auto &LC_THREAD_data : LC_THREAD_datas) {
- const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
- buffer.PutHex32(LC_THREAD);
- buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
- buffer.Write(LC_THREAD_data.GetString().data(),
- LC_THREAD_data_size);
- }
-
- // Write out all of the segment load commands
- for (const auto &segment : segment_load_commands) {
- printf("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
- ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64
- ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
- segment.cmd, segment.cmdsize, segment.vmaddr,
- segment.vmaddr + segment.vmsize, segment.fileoff,
- segment.filesize, segment.maxprot, segment.initprot,
- segment.nsects, segment.flags);
-
- buffer.PutHex32(segment.cmd);
- buffer.PutHex32(segment.cmdsize);
- buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
- if (addr_byte_size == 8) {
- buffer.PutHex64(segment.vmaddr);
- buffer.PutHex64(segment.vmsize);
- buffer.PutHex64(segment.fileoff);
- buffer.PutHex64(segment.filesize);
- } else {
- buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
- buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
- buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
- buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
- }
- buffer.PutHex32(segment.maxprot);
- buffer.PutHex32(segment.initprot);
- buffer.PutHex32(segment.nsects);
- buffer.PutHex32(segment.flags);
- }
-
- File core_file;
- std::string core_file_path(outfile.GetPath());
- error = FileSystem::Instance().Open(core_file, outfile,
- File::eOpenOptionWrite |
- File::eOpenOptionTruncate |
- File::eOpenOptionCanCreate);
- if (error.Success()) {
- // Read 1 page at a time
- uint8_t bytes[0x1000];
- // Write the mach header and load commands out to the core file
- size_t bytes_written = buffer.GetString().size();
- error = core_file.Write(buffer.GetString().data(), bytes_written);
- if (error.Success()) {
- // Now write the file data for all memory segments in the process
- for (const auto &segment : segment_load_commands) {
- if (core_file.SeekFromStart(segment.fileoff) == -1) {
- error.SetErrorStringWithFormat(
- "unable to seek to offset 0x%" PRIx64 " in '%s'",
- segment.fileoff, core_file_path.c_str());
- break;
- }
-
- printf("Saving %" PRId64
- " bytes of data for memory region at 0x%" PRIx64 "\n",
- segment.vmsize, segment.vmaddr);
- addr_t bytes_left = segment.vmsize;
- addr_t addr = segment.vmaddr;
- Status memory_read_error;
- while (bytes_left > 0 && error.Success()) {
- const size_t bytes_to_read =
- bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
- const size_t bytes_read = process_sp->ReadMemory(
- addr, bytes, bytes_to_read, memory_read_error);
- if (bytes_read == bytes_to_read) {
- size_t bytes_written = bytes_read;
- error = core_file.Write(bytes, bytes_written);
- bytes_left -= bytes_read;
- addr += bytes_read;
- } else {
- // Some pages within regions are not readable, those should
- // be zero filled
- memset(bytes, 0, bytes_to_read);
- size_t bytes_written = bytes_to_read;
- error = core_file.Write(bytes, bytes_written);
- bytes_left -= bytes_to_read;
- addr += bytes_to_read;
- }
- }
- }
- }
- }
- } else {
- error.SetErrorString(
- "process doesn't support getting memory region info");
- }
- }
- return true; // This is the right plug to handle saving core files for
- // this process
- }
- }
- return false;
-}
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
deleted file mode 100644
index 196abae807e90..0000000000000
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ /dev/null
@@ -1,220 +0,0 @@
-//===-- ObjectFileMachO.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_ObjectFileMachO_h_
-#define liblldb_ObjectFileMachO_h_
-
-#include "lldb/Core/Address.h"
-#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/RangeMap.h"
-#include "lldb/Host/SafeMachO.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/UUID.h"
-
-//----------------------------------------------------------------------
-// This class needs to be hidden as eventually belongs in a plugin that
-// will export the ObjectFile protocol
-//----------------------------------------------------------------------
-class ObjectFileMachO : public lldb_private::ObjectFile {
-public:
- ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file, lldb::offset_t offset,
- lldb::offset_t length);
-
- ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
-
- ~ObjectFileMachO() override = default;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::ObjectFile *
- CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset, const lldb_private::FileSpec *file,
- lldb::offset_t file_offset, lldb::offset_t length);
-
- static lldb_private::ObjectFile *CreateMemoryInstance(
- const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
-
- static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
- lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool SaveCore(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Status &error);
-
- static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,
- lldb::addr_t length);
-
- //------------------------------------------------------------------
- // Member Functions
- //------------------------------------------------------------------
- bool ParseHeader() override;
-
- bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
- bool value_is_offset) override;
-
- lldb::ByteOrder GetByteOrder() const override;
-
- bool IsExecutable() const override;
-
- uint32_t GetAddressByteSize() const override;
-
- lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
-
- lldb_private::Symtab *GetSymtab() override;
-
- bool IsStripped() override;
-
- void CreateSections(lldb_private::SectionList &unified_section_list) override;
-
- void Dump(lldb_private::Stream *s) override;
-
- lldb_private::ArchSpec GetArchitecture() override;
-
- bool GetUUID(lldb_private::UUID *uuid) override;
-
- uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
-
- lldb_private::FileSpecList GetReExportedLibraries() override {
- return m_reexported_dylibs;
- }
-
- lldb_private::Address GetEntryPointAddress() override;
-
- lldb_private::Address GetBaseAddress() override;
-
- uint32_t GetNumThreadContexts() override;
-
- std::string GetIdentifierString() override;
-
- bool GetCorefileMainBinaryInfo (lldb::addr_t &address, lldb_private::UUID &uuid) override;
-
- lldb::RegisterContextSP
- GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override;
-
- ObjectFile::Type CalculateType() override;
-
- ObjectFile::Strata CalculateStrata() override;
-
- llvm::VersionTuple GetVersion() override;
-
- llvm::VersionTuple GetMinimumOSVersion() override;
-
- uint32_t GetSDKVersion(uint32_t *versions, uint32_t num_versions) override;
-
- bool GetIsDynamicLinkEditor() override;
-
- static bool ParseHeader(lldb_private::DataExtractor &data,
- lldb::offset_t *data_offset_ptr,
- llvm::MachO::mach_header &header);
-
- bool AllowAssemblyEmulationUnwindPlans() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
-protected:
- static bool
- GetUUID(const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- lldb::offset_t lc_offset, // Offset to the first load command
- lldb_private::UUID &uuid);
-
- static lldb_private::ArchSpec
- GetArchitecture(const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- lldb::offset_t lc_offset);
-
- // Intended for same-host arm device debugging where lldb needs to
- // detect libraries in the shared cache and augment the nlist entries
- // with an on-disk dyld_shared_cache file. The process will record
- // the shared cache UUID so the on-disk cache can be matched or rejected
- // correctly.
- void GetProcessSharedCacheUUID(lldb_private::Process *, lldb::addr_t &base_addr, lldb_private::UUID &uuid);
-
- // Intended for same-host arm device debugging where lldb will read
- // shared cache libraries out of its own memory instead of the remote
- // process' memory as an optimization. If lldb's shared cache UUID
- // does not match the process' shared cache UUID, this optimization
- // should not be used.
- void GetLLDBSharedCacheUUID(lldb::addr_t &base_addir, lldb_private::UUID &uuid);
-
- lldb_private::Section *GetMachHeaderSection();
-
- lldb::addr_t CalculateSectionLoadAddressForMemoryImage(
- lldb::addr_t mach_header_load_address,
- const lldb_private::Section *mach_header_section,
- const lldb_private::Section *section);
-
- lldb_private::UUID
- GetSharedCacheUUID(lldb_private::FileSpec dyld_shared_cache,
- const lldb::ByteOrder byte_order,
- const uint32_t addr_byte_size);
-
- size_t ParseSymtab();
-
- typedef lldb_private::RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
- EncryptedFileRanges GetEncryptedFileRanges();
-
- struct SegmentParsingContext;
- void ProcessDysymtabCommand(const llvm::MachO::load_command &load_cmd,
- lldb::offset_t offset);
- void ProcessSegmentCommand(const llvm::MachO::load_command &load_cmd,
- lldb::offset_t offset, uint32_t cmd_idx,
- SegmentParsingContext &context);
- void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd,
- uint32_t cmd_idx);
-
- bool SectionIsLoadable(const lldb_private::Section *section);
-
- llvm::MachO::mach_header m_header;
- static const lldb_private::ConstString &GetSegmentNameTEXT();
- static const lldb_private::ConstString &GetSegmentNameDATA();
- static const lldb_private::ConstString &GetSegmentNameDATA_DIRTY();
- static const lldb_private::ConstString &GetSegmentNameDATA_CONST();
- static const lldb_private::ConstString &GetSegmentNameOBJC();
- static const lldb_private::ConstString &GetSegmentNameLINKEDIT();
- static const lldb_private::ConstString &GetSegmentNameDWARF();
- static const lldb_private::ConstString &GetSectionNameEHFrame();
-
- llvm::MachO::dysymtab_command m_dysymtab;
- std::vector<llvm::MachO::segment_command_64> m_mach_segments;
- std::vector<llvm::MachO::section_64> m_mach_sections;
- llvm::Optional<llvm::VersionTuple> m_min_os_version;
- std::vector<uint32_t> m_sdk_versions;
- typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
- lldb_private::Address m_entry_point_address;
- FileRangeArray m_thread_context_offsets;
- bool m_thread_context_offsets_valid;
- lldb_private::FileSpecList m_reexported_dylibs;
- bool m_allow_assembly_emulation_unwind_plans;
-};
-
-#endif // liblldb_ObjectFileMachO_h_
diff --git a/source/Plugins/ObjectFile/PECOFF/CMakeLists.txt b/source/Plugins/ObjectFile/PECOFF/CMakeLists.txt
deleted file mode 100644
index 04321f2765510..0000000000000
--- a/source/Plugins/ObjectFile/PECOFF/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginObjectFilePECOFF PLUGIN
- ObjectFilePECOFF.cpp
- WindowsMiniDump.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- BinaryFormat
- Support
- )
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
deleted file mode 100644
index d18ff617521f5..0000000000000
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ /dev/null
@@ -1,1183 +0,0 @@
-//===-- ObjectFilePECOFF.cpp ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ObjectFilePECOFF.h"
-#include "WindowsMiniDump.h"
-
-#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Core/StreamFile.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/SectionLoadList.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-#include "lldb/Utility/UUID.h"
-#include "llvm/BinaryFormat/COFF.h"
-
-#include "llvm/Object/COFFImportFile.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
-#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
-#define OPT_HEADER_MAGIC_PE32 0x010b
-#define OPT_HEADER_MAGIC_PE32_PLUS 0x020b
-
-using namespace lldb;
-using namespace lldb_private;
-
-void ObjectFilePECOFF::Initialize() {
- PluginManager::RegisterPlugin(
- GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
- CreateMemoryInstance, GetModuleSpecifications, SaveCore);
-}
-
-void ObjectFilePECOFF::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString ObjectFilePECOFF::GetPluginNameStatic() {
- static ConstString g_name("pe-coff");
- return g_name;
-}
-
-const char *ObjectFilePECOFF::GetPluginDescriptionStatic() {
- return "Portable Executable and Common Object File Format object file reader "
- "(32 and 64 bit)";
-}
-
-ObjectFile *ObjectFilePECOFF::CreateInstance(const lldb::ModuleSP &module_sp,
- DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t length) {
- if (!data_sp) {
- data_sp = MapFileData(file, length, file_offset);
- if (!data_sp)
- return nullptr;
- data_offset = 0;
- }
-
- if (!ObjectFilePECOFF::MagicBytesMatch(data_sp))
- return nullptr;
-
- // Update the data to contain the entire file if it doesn't already
- if (data_sp->GetByteSize() < length) {
- data_sp = MapFileData(file, length, file_offset);
- if (!data_sp)
- return nullptr;
- }
-
- auto objfile_ap = llvm::make_unique<ObjectFilePECOFF>(
- module_sp, data_sp, data_offset, file, file_offset, length);
- if (!objfile_ap || !objfile_ap->ParseHeader())
- return nullptr;
-
- // Cache coff binary.
- if (!objfile_ap->CreateBinary())
- return nullptr;
-
- return objfile_ap.release();
-}
-
-ObjectFile *ObjectFilePECOFF::CreateMemoryInstance(
- const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
- if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp))
- return nullptr;
- auto objfile_ap = llvm::make_unique<ObjectFilePECOFF>(
- module_sp, data_sp, process_sp, header_addr);
- if (objfile_ap.get() && objfile_ap->ParseHeader()) {
- return objfile_ap.release();
- }
- return nullptr;
-}
-
-size_t ObjectFilePECOFF::GetModuleSpecifications(
- const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset, lldb::offset_t file_offset,
- lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
- const size_t initial_count = specs.GetSize();
-
- if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) {
- DataExtractor data;
- data.SetData(data_sp, data_offset, length);
- data.SetByteOrder(eByteOrderLittle);
-
- dos_header_t dos_header;
- coff_header_t coff_header;
-
- if (ParseDOSHeader(data, dos_header)) {
- lldb::offset_t offset = dos_header.e_lfanew;
- uint32_t pe_signature = data.GetU32(&offset);
- if (pe_signature != IMAGE_NT_SIGNATURE)
- return false;
- if (ParseCOFFHeader(data, &offset, coff_header)) {
- ArchSpec spec;
- if (coff_header.machine == MachineAmd64) {
- spec.SetTriple("x86_64-pc-windows");
- specs.Append(ModuleSpec(file, spec));
- } else if (coff_header.machine == MachineX86) {
- spec.SetTriple("i386-pc-windows");
- specs.Append(ModuleSpec(file, spec));
- spec.SetTriple("i686-pc-windows");
- specs.Append(ModuleSpec(file, spec));
- } else if (coff_header.machine == MachineArmNt) {
- spec.SetTriple("arm-pc-windows");
- specs.Append(ModuleSpec(file, spec));
- }
- }
- }
- }
-
- return specs.GetSize() - initial_count;
-}
-
-bool ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Status &error) {
- return SaveMiniDump(process_sp, outfile, error);
-}
-
-bool ObjectFilePECOFF::MagicBytesMatch(DataBufferSP &data_sp) {
- DataExtractor data(data_sp, eByteOrderLittle, 4);
- lldb::offset_t offset = 0;
- uint16_t magic = data.GetU16(&offset);
- return magic == IMAGE_DOS_SIGNATURE;
-}
-
-lldb::SymbolType ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type) {
- // TODO: We need to complete this mapping of COFF symbol types to LLDB ones.
- // For now, here's a hack to make sure our function have types.
- const auto complex_type =
- coff_symbol_type >> llvm::COFF::SCT_COMPLEX_TYPE_SHIFT;
- if (complex_type == llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION) {
- return lldb::eSymbolTypeCode;
- }
- return lldb::eSymbolTypeInvalid;
-}
-
-bool ObjectFilePECOFF::CreateBinary() {
- if (m_owningbin)
- return true;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
-
- auto binary = llvm::object::createBinary(m_file.GetPath());
- if (!binary) {
- if (log)
- log->Printf("ObjectFilePECOFF::CreateBinary() - failed to create binary "
- "for file (%s): %s",
- m_file ? m_file.GetPath().c_str() : "<NULL>",
- errorToErrorCode(binary.takeError()).message().c_str());
- return false;
- }
-
- // Make sure we only handle COFF format.
- if (!binary->getBinary()->isCOFF() &&
- !binary->getBinary()->isCOFFImportFile())
- return false;
-
- m_owningbin = OWNBINType(std::move(*binary));
- if (log)
- log->Printf("%p ObjectFilePECOFF::CreateBinary() module = %p (%s), file = "
- "%s, binary = %p (Bin = %p)",
- static_cast<void *>(this),
- static_cast<void *>(GetModule().get()),
- GetModule()->GetSpecificationDescription().c_str(),
- m_file ? m_file.GetPath().c_str() : "<NULL>",
- static_cast<void *>(m_owningbin.getPointer()),
- static_cast<void *>(m_owningbin->getBinary()));
- return true;
-}
-
-ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
- DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t length)
- : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
- m_entry_point_address(), m_deps_filespec(), m_owningbin() {
- ::memset(&m_dos_header, 0, sizeof(m_dos_header));
- ::memset(&m_coff_header, 0, sizeof(m_coff_header));
- ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
-}
-
-ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
- DataBufferSP &header_data_sp,
- const lldb::ProcessSP &process_sp,
- addr_t header_addr)
- : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
- m_entry_point_address(), m_deps_filespec(), m_owningbin() {
- ::memset(&m_dos_header, 0, sizeof(m_dos_header));
- ::memset(&m_coff_header, 0, sizeof(m_coff_header));
- ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
-}
-
-ObjectFilePECOFF::~ObjectFilePECOFF() {}
-
-bool ObjectFilePECOFF::ParseHeader() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- m_sect_headers.clear();
- m_data.SetByteOrder(eByteOrderLittle);
- lldb::offset_t offset = 0;
-
- if (ParseDOSHeader(m_data, m_dos_header)) {
- offset = m_dos_header.e_lfanew;
- uint32_t pe_signature = m_data.GetU32(&offset);
- if (pe_signature != IMAGE_NT_SIGNATURE)
- return false;
- if (ParseCOFFHeader(m_data, &offset, m_coff_header)) {
- if (m_coff_header.hdrsize > 0)
- ParseCOFFOptionalHeader(&offset);
- ParseSectionHeaders(offset);
- }
- return true;
- }
- }
- return false;
-}
-
-bool ObjectFilePECOFF::SetLoadAddress(Target &target, addr_t value,
- bool value_is_offset) {
- bool changed = false;
- ModuleSP module_sp = GetModule();
- if (module_sp) {
- size_t num_loaded_sections = 0;
- SectionList *section_list = GetSectionList();
- if (section_list) {
- if (!value_is_offset) {
- value -= m_image_base;
- }
-
- const size_t num_sections = section_list->GetSize();
- size_t sect_idx = 0;
-
- for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find all of the sections
- // that have SHF_ALLOC in their flag bits.
- SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
- if (section_sp && !section_sp->IsThreadSpecific()) {
- if (target.GetSectionLoadList().SetSectionLoadAddress(
- section_sp, section_sp->GetFileAddress() + value))
- ++num_loaded_sections;
- }
- }
- changed = num_loaded_sections > 0;
- }
- }
- return changed;
-}
-
-ByteOrder ObjectFilePECOFF::GetByteOrder() const { return eByteOrderLittle; }
-
-bool ObjectFilePECOFF::IsExecutable() const {
- return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0;
-}
-
-uint32_t ObjectFilePECOFF::GetAddressByteSize() const {
- if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
- return 8;
- else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
- return 4;
- return 4;
-}
-
-//----------------------------------------------------------------------
-// NeedsEndianSwap
-//
-// Return true if an endian swap needs to occur when extracting data from this
-// file.
-//----------------------------------------------------------------------
-bool ObjectFilePECOFF::NeedsEndianSwap() const {
-#if defined(__LITTLE_ENDIAN__)
- return false;
-#else
- return true;
-#endif
-}
-//----------------------------------------------------------------------
-// ParseDOSHeader
-//----------------------------------------------------------------------
-bool ObjectFilePECOFF::ParseDOSHeader(DataExtractor &data,
- dos_header_t &dos_header) {
- bool success = false;
- lldb::offset_t offset = 0;
- success = data.ValidOffsetForDataOfSize(0, sizeof(dos_header));
-
- if (success) {
- dos_header.e_magic = data.GetU16(&offset); // Magic number
- success = dos_header.e_magic == IMAGE_DOS_SIGNATURE;
-
- if (success) {
- dos_header.e_cblp = data.GetU16(&offset); // Bytes on last page of file
- dos_header.e_cp = data.GetU16(&offset); // Pages in file
- dos_header.e_crlc = data.GetU16(&offset); // Relocations
- dos_header.e_cparhdr =
- data.GetU16(&offset); // Size of header in paragraphs
- dos_header.e_minalloc =
- data.GetU16(&offset); // Minimum extra paragraphs needed
- dos_header.e_maxalloc =
- data.GetU16(&offset); // Maximum extra paragraphs needed
- dos_header.e_ss = data.GetU16(&offset); // Initial (relative) SS value
- dos_header.e_sp = data.GetU16(&offset); // Initial SP value
- dos_header.e_csum = data.GetU16(&offset); // Checksum
- dos_header.e_ip = data.GetU16(&offset); // Initial IP value
- dos_header.e_cs = data.GetU16(&offset); // Initial (relative) CS value
- dos_header.e_lfarlc =
- data.GetU16(&offset); // File address of relocation table
- dos_header.e_ovno = data.GetU16(&offset); // Overlay number
-
- dos_header.e_res[0] = data.GetU16(&offset); // Reserved words
- dos_header.e_res[1] = data.GetU16(&offset); // Reserved words
- dos_header.e_res[2] = data.GetU16(&offset); // Reserved words
- dos_header.e_res[3] = data.GetU16(&offset); // Reserved words
-
- dos_header.e_oemid =
- data.GetU16(&offset); // OEM identifier (for e_oeminfo)
- dos_header.e_oeminfo =
- data.GetU16(&offset); // OEM information; e_oemid specific
- dos_header.e_res2[0] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[1] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[2] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[3] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[4] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[5] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[6] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[7] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[8] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[9] = data.GetU16(&offset); // Reserved words
-
- dos_header.e_lfanew =
- data.GetU32(&offset); // File address of new exe header
- }
- }
- if (!success)
- memset(&dos_header, 0, sizeof(dos_header));
- return success;
-}
-
-//----------------------------------------------------------------------
-// ParserCOFFHeader
-//----------------------------------------------------------------------
-bool ObjectFilePECOFF::ParseCOFFHeader(DataExtractor &data,
- lldb::offset_t *offset_ptr,
- coff_header_t &coff_header) {
- bool success =
- data.ValidOffsetForDataOfSize(*offset_ptr, sizeof(coff_header));
- if (success) {
- coff_header.machine = data.GetU16(offset_ptr);
- coff_header.nsects = data.GetU16(offset_ptr);
- coff_header.modtime = data.GetU32(offset_ptr);
- coff_header.symoff = data.GetU32(offset_ptr);
- coff_header.nsyms = data.GetU32(offset_ptr);
- coff_header.hdrsize = data.GetU16(offset_ptr);
- coff_header.flags = data.GetU16(offset_ptr);
- }
- if (!success)
- memset(&coff_header, 0, sizeof(coff_header));
- return success;
-}
-
-bool ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr) {
- bool success = false;
- const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
- if (*offset_ptr < end_offset) {
- success = true;
- m_coff_header_opt.magic = m_data.GetU16(offset_ptr);
- m_coff_header_opt.major_linker_version = m_data.GetU8(offset_ptr);
- m_coff_header_opt.minor_linker_version = m_data.GetU8(offset_ptr);
- m_coff_header_opt.code_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.data_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.bss_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.entry = m_data.GetU32(offset_ptr);
- m_coff_header_opt.code_offset = m_data.GetU32(offset_ptr);
-
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- if (*offset_ptr < end_offset) {
- if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) {
- // PE32 only
- m_coff_header_opt.data_offset = m_data.GetU32(offset_ptr);
- } else
- m_coff_header_opt.data_offset = 0;
-
- if (*offset_ptr < end_offset) {
- m_coff_header_opt.image_base =
- m_data.GetMaxU64(offset_ptr, addr_byte_size);
- m_coff_header_opt.sect_alignment = m_data.GetU32(offset_ptr);
- m_coff_header_opt.file_alignment = m_data.GetU32(offset_ptr);
- m_coff_header_opt.major_os_system_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.minor_os_system_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.major_image_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.minor_image_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.major_subsystem_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.minor_subsystem_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr);
- m_coff_header_opt.image_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.header_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.checksum = m_data.GetU32(offset_ptr);
- m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr);
- m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr);
- m_coff_header_opt.stack_reserve_size =
- m_data.GetMaxU64(offset_ptr, addr_byte_size);
- m_coff_header_opt.stack_commit_size =
- m_data.GetMaxU64(offset_ptr, addr_byte_size);
- m_coff_header_opt.heap_reserve_size =
- m_data.GetMaxU64(offset_ptr, addr_byte_size);
- m_coff_header_opt.heap_commit_size =
- m_data.GetMaxU64(offset_ptr, addr_byte_size);
- m_coff_header_opt.loader_flags = m_data.GetU32(offset_ptr);
- uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr);
- m_coff_header_opt.data_dirs.clear();
- m_coff_header_opt.data_dirs.resize(num_data_dir_entries);
- uint32_t i;
- for (i = 0; i < num_data_dir_entries; i++) {
- m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr);
- m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr);
- }
-
- m_file_offset = m_coff_header_opt.image_base;
- m_image_base = m_coff_header_opt.image_base;
- }
- }
- }
- // Make sure we are on track for section data which follows
- *offset_ptr = end_offset;
- return success;
-}
-
-DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
- if (m_file) {
- // A bit of a hack, but we intend to write to this buffer, so we can't
- // mmap it.
- auto buffer_sp = MapFileData(m_file, size, offset);
- return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
- }
- ProcessSP process_sp(m_process_wp.lock());
- DataExtractor data;
- if (process_sp) {
- auto data_ap = llvm::make_unique<DataBufferHeap>(size, 0);
- Status readmem_error;
- size_t bytes_read =
- process_sp->ReadMemory(m_image_base + offset, data_ap->GetBytes(),
- data_ap->GetByteSize(), readmem_error);
- if (bytes_read == size) {
- DataBufferSP buffer_sp(data_ap.release());
- data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
- }
- }
- return data;
-}
-
-//----------------------------------------------------------------------
-// ParseSectionHeaders
-//----------------------------------------------------------------------
-bool ObjectFilePECOFF::ParseSectionHeaders(
- uint32_t section_header_data_offset) {
- const uint32_t nsects = m_coff_header.nsects;
- m_sect_headers.clear();
-
- if (nsects > 0) {
- const size_t section_header_byte_size = nsects * sizeof(section_header_t);
- DataExtractor section_header_data =
- ReadImageData(section_header_data_offset, section_header_byte_size);
-
- lldb::offset_t offset = 0;
- if (section_header_data.ValidOffsetForDataOfSize(
- offset, section_header_byte_size)) {
- m_sect_headers.resize(nsects);
-
- for (uint32_t idx = 0; idx < nsects; ++idx) {
- const void *name_data = section_header_data.GetData(&offset, 8);
- if (name_data) {
- memcpy(m_sect_headers[idx].name, name_data, 8);
- m_sect_headers[idx].vmsize = section_header_data.GetU32(&offset);
- m_sect_headers[idx].vmaddr = section_header_data.GetU32(&offset);
- m_sect_headers[idx].size = section_header_data.GetU32(&offset);
- m_sect_headers[idx].offset = section_header_data.GetU32(&offset);
- m_sect_headers[idx].reloff = section_header_data.GetU32(&offset);
- m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset);
- m_sect_headers[idx].nreloc = section_header_data.GetU16(&offset);
- m_sect_headers[idx].nline = section_header_data.GetU16(&offset);
- m_sect_headers[idx].flags = section_header_data.GetU32(&offset);
- }
- }
- }
- }
-
- return !m_sect_headers.empty();
-}
-
-llvm::StringRef ObjectFilePECOFF::GetSectionName(const section_header_t &sect) {
- llvm::StringRef hdr_name(sect.name, llvm::array_lengthof(sect.name));
- hdr_name = hdr_name.split('\0').first;
- if (hdr_name.consume_front("/")) {
- lldb::offset_t stroff;
- if (!to_integer(hdr_name, stroff, 10))
- return "";
- lldb::offset_t string_file_offset =
- m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
- if (const char *name = m_data.GetCStr(&string_file_offset))
- return name;
- return "";
- }
- return hdr_name;
-}
-
-//----------------------------------------------------------------------
-// GetNListSymtab
-//----------------------------------------------------------------------
-Symtab *ObjectFilePECOFF::GetSymtab() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_symtab_ap.get() == NULL) {
- SectionList *sect_list = GetSectionList();
- m_symtab_ap.reset(new Symtab(this));
- std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex());
-
- const uint32_t num_syms = m_coff_header.nsyms;
-
- if (m_file && num_syms > 0 && m_coff_header.symoff > 0) {
- const uint32_t symbol_size = 18;
- const size_t symbol_data_size = num_syms * symbol_size;
- // Include the 4-byte string table size at the end of the symbols
- DataExtractor symtab_data =
- ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
- lldb::offset_t offset = symbol_data_size;
- const uint32_t strtab_size = symtab_data.GetU32(&offset);
- if (strtab_size > 0) {
- DataExtractor strtab_data = ReadImageData(
- m_coff_header.symoff + symbol_data_size, strtab_size);
-
- // First 4 bytes should be zeroed after strtab_size has been read,
- // because it is used as offset 0 to encode a NULL string.
- uint32_t *strtab_data_start = const_cast<uint32_t *>(
- reinterpret_cast<const uint32_t *>(strtab_data.GetDataStart()));
- strtab_data_start[0] = 0;
-
- offset = 0;
- std::string symbol_name;
- Symbol *symbols = m_symtab_ap->Resize(num_syms);
- for (uint32_t i = 0; i < num_syms; ++i) {
- coff_symbol_t symbol;
- const uint32_t symbol_offset = offset;
- const char *symbol_name_cstr = NULL;
- // If the first 4 bytes of the symbol string are zero, then they
- // are followed by a 4-byte string table offset. Else these
- // 8 bytes contain the symbol name
- if (symtab_data.GetU32(&offset) == 0) {
- // Long string that doesn't fit into the symbol table name, so
- // now we must read the 4 byte string table offset
- uint32_t strtab_offset = symtab_data.GetU32(&offset);
- symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
- symbol_name.assign(symbol_name_cstr);
- } else {
- // Short string that fits into the symbol table name which is 8
- // bytes
- offset += sizeof(symbol.name) - 4; // Skip remaining
- symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
- if (symbol_name_cstr == NULL)
- break;
- symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
- }
- symbol.value = symtab_data.GetU32(&offset);
- symbol.sect = symtab_data.GetU16(&offset);
- symbol.type = symtab_data.GetU16(&offset);
- symbol.storage = symtab_data.GetU8(&offset);
- symbol.naux = symtab_data.GetU8(&offset);
- symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
- if ((int16_t)symbol.sect >= 1) {
- Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect - 1),
- symbol.value);
- symbols[i].GetAddressRef() = symbol_addr;
- symbols[i].SetType(MapSymbolType(symbol.type));
- }
-
- if (symbol.naux > 0) {
- i += symbol.naux;
- offset += symbol_size;
- }
- }
- }
- }
-
- // Read export header
- if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() &&
- m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 &&
- m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) {
- export_directory_entry export_table;
- uint32_t data_start =
- m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
-
- uint32_t address_rva = data_start;
- if (m_file) {
- Address address(m_coff_header_opt.image_base + data_start, sect_list);
- address_rva =
- address.GetSection()->GetFileOffset() + address.GetOffset();
- }
- DataExtractor symtab_data =
- ReadImageData(address_rva, m_coff_header_opt.data_dirs[0].vmsize);
- lldb::offset_t offset = 0;
-
- // Read export_table header
- export_table.characteristics = symtab_data.GetU32(&offset);
- export_table.time_date_stamp = symtab_data.GetU32(&offset);
- export_table.major_version = symtab_data.GetU16(&offset);
- export_table.minor_version = symtab_data.GetU16(&offset);
- export_table.name = symtab_data.GetU32(&offset);
- export_table.base = symtab_data.GetU32(&offset);
- export_table.number_of_functions = symtab_data.GetU32(&offset);
- export_table.number_of_names = symtab_data.GetU32(&offset);
- export_table.address_of_functions = symtab_data.GetU32(&offset);
- export_table.address_of_names = symtab_data.GetU32(&offset);
- export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
-
- bool has_ordinal = export_table.address_of_name_ordinals != 0;
-
- lldb::offset_t name_offset = export_table.address_of_names - data_start;
- lldb::offset_t name_ordinal_offset =
- export_table.address_of_name_ordinals - data_start;
-
- Symbol *symbols = m_symtab_ap->Resize(export_table.number_of_names);
-
- std::string symbol_name;
-
- // Read each export table entry
- for (size_t i = 0; i < export_table.number_of_names; ++i) {
- uint32_t name_ordinal =
- has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
- uint32_t name_address = symtab_data.GetU32(&name_offset);
-
- const char *symbol_name_cstr =
- symtab_data.PeekCStr(name_address - data_start);
- symbol_name.assign(symbol_name_cstr);
-
- lldb::offset_t function_offset = export_table.address_of_functions -
- data_start +
- sizeof(uint32_t) * name_ordinal;
- uint32_t function_rva = symtab_data.GetU32(&function_offset);
-
- Address symbol_addr(m_coff_header_opt.image_base + function_rva,
- sect_list);
- symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
- symbols[i].GetAddressRef() = symbol_addr;
- symbols[i].SetType(lldb::eSymbolTypeCode);
- symbols[i].SetDebug(true);
- }
- }
- m_symtab_ap->CalculateSymbolSizes();
- }
- }
- return m_symtab_ap.get();
-}
-
-bool ObjectFilePECOFF::IsStripped() {
- // TODO: determine this for COFF
- return false;
-}
-
-void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
- if (m_sections_ap)
- return;
- m_sections_ap.reset(new SectionList());
-
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- const uint32_t nsects = m_sect_headers.size();
- ModuleSP module_sp(GetModule());
- for (uint32_t idx = 0; idx < nsects; ++idx) {
- ConstString const_sect_name(GetSectionName(m_sect_headers[idx]));
- static ConstString g_code_sect_name(".code");
- static ConstString g_CODE_sect_name("CODE");
- static ConstString g_data_sect_name(".data");
- static ConstString g_DATA_sect_name("DATA");
- static ConstString g_bss_sect_name(".bss");
- static ConstString g_BSS_sect_name("BSS");
- static ConstString g_debug_sect_name(".debug");
- static ConstString g_reloc_sect_name(".reloc");
- static ConstString g_stab_sect_name(".stab");
- static ConstString g_stabstr_sect_name(".stabstr");
- static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev");
- static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges");
- static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
- static ConstString g_sect_name_dwarf_debug_info(".debug_info");
- static ConstString g_sect_name_dwarf_debug_line(".debug_line");
- static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
- static ConstString g_sect_name_dwarf_debug_loclists(".debug_loclists");
- static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
- static ConstString g_sect_name_dwarf_debug_names(".debug_names");
- static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
- static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
- static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
- static ConstString g_sect_name_dwarf_debug_str(".debug_str");
- static ConstString g_sect_name_dwarf_debug_types(".debug_types");
- static ConstString g_sect_name_eh_frame(".eh_frame");
- static ConstString g_sect_name_go_symtab(".gosymtab");
- SectionType section_type = eSectionTypeOther;
- if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE &&
- ((const_sect_name == g_code_sect_name) ||
- (const_sect_name == g_CODE_sect_name))) {
- section_type = eSectionTypeCode;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA &&
- ((const_sect_name == g_data_sect_name) ||
- (const_sect_name == g_DATA_sect_name))) {
- if (m_sect_headers[idx].size == 0 && m_sect_headers[idx].offset == 0)
- section_type = eSectionTypeZeroFill;
- else
- section_type = eSectionTypeData;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA &&
- ((const_sect_name == g_bss_sect_name) ||
- (const_sect_name == g_BSS_sect_name))) {
- if (m_sect_headers[idx].size == 0)
- section_type = eSectionTypeZeroFill;
- else
- section_type = eSectionTypeData;
- } else if (const_sect_name == g_debug_sect_name) {
- section_type = eSectionTypeDebug;
- } else if (const_sect_name == g_stabstr_sect_name) {
- section_type = eSectionTypeDataCString;
- } else if (const_sect_name == g_reloc_sect_name) {
- section_type = eSectionTypeOther;
- } else if (const_sect_name == g_sect_name_dwarf_debug_abbrev)
- section_type = eSectionTypeDWARFDebugAbbrev;
- else if (const_sect_name == g_sect_name_dwarf_debug_aranges)
- section_type = eSectionTypeDWARFDebugAranges;
- else if (const_sect_name == g_sect_name_dwarf_debug_frame)
- section_type = eSectionTypeDWARFDebugFrame;
- else if (const_sect_name == g_sect_name_dwarf_debug_info)
- section_type = eSectionTypeDWARFDebugInfo;
- else if (const_sect_name == g_sect_name_dwarf_debug_line)
- section_type = eSectionTypeDWARFDebugLine;
- else if (const_sect_name == g_sect_name_dwarf_debug_loc)
- section_type = eSectionTypeDWARFDebugLoc;
- else if (const_sect_name == g_sect_name_dwarf_debug_loclists)
- section_type = eSectionTypeDWARFDebugLocLists;
- else if (const_sect_name == g_sect_name_dwarf_debug_macinfo)
- section_type = eSectionTypeDWARFDebugMacInfo;
- else if (const_sect_name == g_sect_name_dwarf_debug_names)
- section_type = eSectionTypeDWARFDebugNames;
- else if (const_sect_name == g_sect_name_dwarf_debug_pubnames)
- section_type = eSectionTypeDWARFDebugPubNames;
- else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes)
- section_type = eSectionTypeDWARFDebugPubTypes;
- else if (const_sect_name == g_sect_name_dwarf_debug_ranges)
- section_type = eSectionTypeDWARFDebugRanges;
- else if (const_sect_name == g_sect_name_dwarf_debug_str)
- section_type = eSectionTypeDWARFDebugStr;
- else if (const_sect_name == g_sect_name_dwarf_debug_types)
- section_type = eSectionTypeDWARFDebugTypes;
- else if (const_sect_name == g_sect_name_eh_frame)
- section_type = eSectionTypeEHFrame;
- else if (const_sect_name == g_sect_name_go_symtab)
- section_type = eSectionTypeGoSymtab;
- else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE) {
- section_type = eSectionTypeCode;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) {
- section_type = eSectionTypeData;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
- if (m_sect_headers[idx].size == 0)
- section_type = eSectionTypeZeroFill;
- else
- section_type = eSectionTypeData;
- }
-
- // Use a segment ID of the segment index shifted left by 8 so they
- // never conflict with any of the sections.
- SectionSP section_sp(new Section(
- module_sp, // Module to which this section belongs
- this, // Object file to which this section belongs
- idx + 1, // Section ID is the 1 based segment index shifted right by
- // 8 bits as not to collide with any of the 256 section IDs
- // that are possible
- const_sect_name, // Name of this section
- section_type, // This section is a container of other sections.
- m_coff_header_opt.image_base +
- m_sect_headers[idx].vmaddr, // File VM address == addresses as
- // they are found in the object file
- m_sect_headers[idx].vmsize, // VM size in bytes of this section
- m_sect_headers[idx]
- .offset, // Offset to the data for this section in the file
- m_sect_headers[idx]
- .size, // Size in bytes of this section as found in the file
- m_coff_header_opt.sect_alignment, // Section alignment
- m_sect_headers[idx].flags)); // Flags for this section
-
- // section_sp->SetIsEncrypted (segment_is_encrypted);
-
- unified_section_list.AddSection(section_sp);
- m_sections_ap->AddSection(section_sp);
- }
- }
-}
-
-bool ObjectFilePECOFF::GetUUID(UUID *uuid) { return false; }
-
-uint32_t ObjectFilePECOFF::ParseDependentModules() {
- ModuleSP module_sp(GetModule());
- if (!module_sp)
- return 0;
-
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_deps_filespec)
- return m_deps_filespec->GetSize();
-
- // Cache coff binary if it is not done yet.
- if (!CreateBinary())
- return 0;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ObjectFilePECOFF::ParseDependentModules() module = %p "
- "(%s), binary = %p (Bin = %p)",
- static_cast<void *>(this), static_cast<void *>(module_sp.get()),
- module_sp->GetSpecificationDescription().c_str(),
- static_cast<void *>(m_owningbin.getPointer()),
- m_owningbin ? static_cast<void *>(m_owningbin->getBinary())
- : nullptr);
-
- auto COFFObj =
- llvm::dyn_cast<llvm::object::COFFObjectFile>(m_owningbin->getBinary());
- if (!COFFObj)
- return 0;
-
- m_deps_filespec = FileSpecList();
-
- for (const auto &entry : COFFObj->import_directories()) {
- llvm::StringRef dll_name;
- auto ec = entry.getName(dll_name);
- // Report a bogus entry.
- if (ec != std::error_code()) {
- if (log)
- log->Printf("ObjectFilePECOFF::ParseDependentModules() - failed to get "
- "import directory entry name: %s",
- ec.message().c_str());
- continue;
- }
-
- // At this moment we only have the base name of the DLL. The full path can
- // only be seen after the dynamic loading. Our best guess is Try to get it
- // with the help of the object file's directory.
- llvm::SmallString<128> dll_fullpath;
- FileSpec dll_specs(dll_name);
- dll_specs.GetDirectory().SetString(m_file.GetDirectory().GetCString());
-
- if (!llvm::sys::fs::real_path(dll_specs.GetPath(), dll_fullpath))
- m_deps_filespec->Append(FileSpec(dll_fullpath));
- else {
- // Known DLLs or DLL not found in the object file directory.
- m_deps_filespec->Append(FileSpec(dll_name));
- }
- }
- return m_deps_filespec->GetSize();
-}
-
-uint32_t ObjectFilePECOFF::GetDependentModules(FileSpecList &files) {
- auto num_modules = ParseDependentModules();
- auto original_size = files.GetSize();
-
- for (unsigned i = 0; i < num_modules; ++i)
- files.AppendIfUnique(m_deps_filespec->GetFileSpecAtIndex(i));
-
- return files.GetSize() - original_size;
-}
-
-lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() {
- if (m_entry_point_address.IsValid())
- return m_entry_point_address;
-
- if (!ParseHeader() || !IsExecutable())
- return m_entry_point_address;
-
- SectionList *section_list = GetSectionList();
- addr_t file_addr = m_coff_header_opt.entry + m_coff_header_opt.image_base;
-
- if (!section_list)
- m_entry_point_address.SetOffset(file_addr);
- else
- m_entry_point_address.ResolveAddressUsingFileSections(file_addr, section_list);
- return m_entry_point_address;
-}
-
-//----------------------------------------------------------------------
-// Dump
-//
-// Dump the specifics of the runtime file container (such as any headers
-// segments, sections, etc).
-//----------------------------------------------------------------------
-void ObjectFilePECOFF::Dump(Stream *s) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- s->Printf("%p: ", static_cast<void *>(this));
- s->Indent();
- s->PutCString("ObjectFilePECOFF");
-
- ArchSpec header_arch = GetArchitecture();
-
- *s << ", file = '" << m_file
- << "', arch = " << header_arch.GetArchitectureName() << "\n";
-
- SectionList *sections = GetSectionList();
- if (sections)
- sections->Dump(s, NULL, true, UINT32_MAX);
-
- if (m_symtab_ap.get())
- m_symtab_ap->Dump(s, NULL, eSortOrderNone);
-
- if (m_dos_header.e_magic)
- DumpDOSHeader(s, m_dos_header);
- if (m_coff_header.machine) {
- DumpCOFFHeader(s, m_coff_header);
- if (m_coff_header.hdrsize)
- DumpOptCOFFHeader(s, m_coff_header_opt);
- }
- s->EOL();
- DumpSectionHeaders(s);
- s->EOL();
-
- DumpDependentModules(s);
- s->EOL();
- }
-}
-
-//----------------------------------------------------------------------
-// DumpDOSHeader
-//
-// Dump the MS-DOS header to the specified output stream
-//----------------------------------------------------------------------
-void ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t &header) {
- s->PutCString("MSDOS Header\n");
- s->Printf(" e_magic = 0x%4.4x\n", header.e_magic);
- s->Printf(" e_cblp = 0x%4.4x\n", header.e_cblp);
- s->Printf(" e_cp = 0x%4.4x\n", header.e_cp);
- s->Printf(" e_crlc = 0x%4.4x\n", header.e_crlc);
- s->Printf(" e_cparhdr = 0x%4.4x\n", header.e_cparhdr);
- s->Printf(" e_minalloc = 0x%4.4x\n", header.e_minalloc);
- s->Printf(" e_maxalloc = 0x%4.4x\n", header.e_maxalloc);
- s->Printf(" e_ss = 0x%4.4x\n", header.e_ss);
- s->Printf(" e_sp = 0x%4.4x\n", header.e_sp);
- s->Printf(" e_csum = 0x%4.4x\n", header.e_csum);
- s->Printf(" e_ip = 0x%4.4x\n", header.e_ip);
- s->Printf(" e_cs = 0x%4.4x\n", header.e_cs);
- s->Printf(" e_lfarlc = 0x%4.4x\n", header.e_lfarlc);
- s->Printf(" e_ovno = 0x%4.4x\n", header.e_ovno);
- s->Printf(" e_res[4] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
- header.e_res[0], header.e_res[1], header.e_res[2], header.e_res[3]);
- s->Printf(" e_oemid = 0x%4.4x\n", header.e_oemid);
- s->Printf(" e_oeminfo = 0x%4.4x\n", header.e_oeminfo);
- s->Printf(" e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, "
- "0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
- header.e_res2[0], header.e_res2[1], header.e_res2[2],
- header.e_res2[3], header.e_res2[4], header.e_res2[5],
- header.e_res2[6], header.e_res2[7], header.e_res2[8],
- header.e_res2[9]);
- s->Printf(" e_lfanew = 0x%8.8x\n", header.e_lfanew);
-}
-
-//----------------------------------------------------------------------
-// DumpCOFFHeader
-//
-// Dump the COFF header to the specified output stream
-//----------------------------------------------------------------------
-void ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t &header) {
- s->PutCString("COFF Header\n");
- s->Printf(" machine = 0x%4.4x\n", header.machine);
- s->Printf(" nsects = 0x%4.4x\n", header.nsects);
- s->Printf(" modtime = 0x%8.8x\n", header.modtime);
- s->Printf(" symoff = 0x%8.8x\n", header.symoff);
- s->Printf(" nsyms = 0x%8.8x\n", header.nsyms);
- s->Printf(" hdrsize = 0x%4.4x\n", header.hdrsize);
-}
-
-//----------------------------------------------------------------------
-// DumpOptCOFFHeader
-//
-// Dump the optional COFF header to the specified output stream
-//----------------------------------------------------------------------
-void ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s,
- const coff_opt_header_t &header) {
- s->PutCString("Optional COFF Header\n");
- s->Printf(" magic = 0x%4.4x\n", header.magic);
- s->Printf(" major_linker_version = 0x%2.2x\n",
- header.major_linker_version);
- s->Printf(" minor_linker_version = 0x%2.2x\n",
- header.minor_linker_version);
- s->Printf(" code_size = 0x%8.8x\n", header.code_size);
- s->Printf(" data_size = 0x%8.8x\n", header.data_size);
- s->Printf(" bss_size = 0x%8.8x\n", header.bss_size);
- s->Printf(" entry = 0x%8.8x\n", header.entry);
- s->Printf(" code_offset = 0x%8.8x\n", header.code_offset);
- s->Printf(" data_offset = 0x%8.8x\n", header.data_offset);
- s->Printf(" image_base = 0x%16.16" PRIx64 "\n",
- header.image_base);
- s->Printf(" sect_alignment = 0x%8.8x\n", header.sect_alignment);
- s->Printf(" file_alignment = 0x%8.8x\n", header.file_alignment);
- s->Printf(" major_os_system_version = 0x%4.4x\n",
- header.major_os_system_version);
- s->Printf(" minor_os_system_version = 0x%4.4x\n",
- header.minor_os_system_version);
- s->Printf(" major_image_version = 0x%4.4x\n",
- header.major_image_version);
- s->Printf(" minor_image_version = 0x%4.4x\n",
- header.minor_image_version);
- s->Printf(" major_subsystem_version = 0x%4.4x\n",
- header.major_subsystem_version);
- s->Printf(" minor_subsystem_version = 0x%4.4x\n",
- header.minor_subsystem_version);
- s->Printf(" reserved1 = 0x%8.8x\n", header.reserved1);
- s->Printf(" image_size = 0x%8.8x\n", header.image_size);
- s->Printf(" header_size = 0x%8.8x\n", header.header_size);
- s->Printf(" checksum = 0x%8.8x\n", header.checksum);
- s->Printf(" subsystem = 0x%4.4x\n", header.subsystem);
- s->Printf(" dll_flags = 0x%4.4x\n", header.dll_flags);
- s->Printf(" stack_reserve_size = 0x%16.16" PRIx64 "\n",
- header.stack_reserve_size);
- s->Printf(" stack_commit_size = 0x%16.16" PRIx64 "\n",
- header.stack_commit_size);
- s->Printf(" heap_reserve_size = 0x%16.16" PRIx64 "\n",
- header.heap_reserve_size);
- s->Printf(" heap_commit_size = 0x%16.16" PRIx64 "\n",
- header.heap_commit_size);
- s->Printf(" loader_flags = 0x%8.8x\n", header.loader_flags);
- s->Printf(" num_data_dir_entries = 0x%8.8x\n",
- (uint32_t)header.data_dirs.size());
- uint32_t i;
- for (i = 0; i < header.data_dirs.size(); i++) {
- s->Printf(" data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", i,
- header.data_dirs[i].vmaddr, header.data_dirs[i].vmsize);
- }
-}
-//----------------------------------------------------------------------
-// DumpSectionHeader
-//
-// Dump a single ELF section header to the specified output stream
-//----------------------------------------------------------------------
-void ObjectFilePECOFF::DumpSectionHeader(Stream *s,
- const section_header_t &sh) {
- std::string name = GetSectionName(sh);
- s->Printf("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x "
- "0x%4.4x 0x%8.8x\n",
- name.c_str(), sh.vmaddr, sh.vmsize, sh.offset, sh.size, sh.reloff,
- sh.lineoff, sh.nreloc, sh.nline, sh.flags);
-}
-
-//----------------------------------------------------------------------
-// DumpSectionHeaders
-//
-// Dump all of the ELF section header to the specified output stream
-//----------------------------------------------------------------------
-void ObjectFilePECOFF::DumpSectionHeaders(Stream *s) {
-
- s->PutCString("Section Headers\n");
- s->PutCString("IDX name vm addr vm size file off file "
- "size reloc off line off nreloc nline flags\n");
- s->PutCString("==== ---------------- ---------- ---------- ---------- "
- "---------- ---------- ---------- ------ ------ ----------\n");
-
- uint32_t idx = 0;
- SectionHeaderCollIter pos, end = m_sect_headers.end();
-
- for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) {
- s->Printf("[%2u] ", idx);
- ObjectFilePECOFF::DumpSectionHeader(s, *pos);
- }
-}
-
-//----------------------------------------------------------------------
-// DumpDependentModules
-//
-// Dump all of the dependent modules to the specified output stream
-//----------------------------------------------------------------------
-void ObjectFilePECOFF::DumpDependentModules(lldb_private::Stream *s) {
- auto num_modules = ParseDependentModules();
- if (num_modules > 0) {
- s->PutCString("Dependent Modules\n");
- for (unsigned i = 0; i < num_modules; ++i) {
- auto spec = m_deps_filespec->GetFileSpecAtIndex(i);
- s->Printf(" %s\n", spec.GetFilename().GetCString());
- }
- }
-}
-
-bool ObjectFilePECOFF::IsWindowsSubsystem() {
- switch (m_coff_header_opt.subsystem) {
- case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE:
- case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI:
- case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI:
- case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE_WINDOWS:
- case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
- case llvm::COFF::IMAGE_SUBSYSTEM_XBOX:
- case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION:
- return true;
- default:
- return false;
- }
-}
-
-ArchSpec ObjectFilePECOFF::GetArchitecture() {
- uint16_t machine = m_coff_header.machine;
- switch (machine) {
- default:
- break;
- case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
- case llvm::COFF::IMAGE_FILE_MACHINE_I386:
- case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC:
- case llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP:
- case llvm::COFF::IMAGE_FILE_MACHINE_ARM:
- case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
- case llvm::COFF::IMAGE_FILE_MACHINE_THUMB:
- ArchSpec arch;
- arch.SetArchitecture(eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE,
- IsWindowsSubsystem() ? llvm::Triple::Win32
- : llvm::Triple::UnknownOS);
- return arch;
- }
- return ArchSpec();
-}
-
-ObjectFile::Type ObjectFilePECOFF::CalculateType() {
- if (m_coff_header.machine != 0) {
- if ((m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0)
- return eTypeExecutable;
- else
- return eTypeSharedLibrary;
- }
- return eTypeExecutable;
-}
-
-ObjectFile::Strata ObjectFilePECOFF::CalculateStrata() { return eStrataUser; }
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-ConstString ObjectFilePECOFF::GetPluginName() { return GetPluginNameStatic(); }
-
-uint32_t ObjectFilePECOFF::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
deleted file mode 100644
index 9fd313f26a0a2..0000000000000
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ /dev/null
@@ -1,294 +0,0 @@
-//===-- ObjectFilePECOFF.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_ObjectFilePECOFF_h_
-#define liblldb_ObjectFilePECOFF_h_
-
-#include <vector>
-
-#include "lldb/Symbol/ObjectFile.h"
-#include "llvm/Object/Binary.h"
-
-class ObjectFilePECOFF : public lldb_private::ObjectFile {
-public:
- typedef enum MachineType {
- MachineUnknown = 0x0,
- MachineAm33 = 0x1d3,
- MachineAmd64 = 0x8664,
- MachineArm = 0x1c0,
- MachineArmNt = 0x1c4,
- MachineArm64 = 0xaa64,
- MachineEbc = 0xebc,
- MachineX86 = 0x14c,
- MachineIA64 = 0x200,
- MachineM32R = 0x9041,
- MachineMips16 = 0x266,
- MachineMipsFpu = 0x366,
- MachineMipsFpu16 = 0x466,
- MachinePowerPc = 0x1f0,
- MachinePowerPcfp = 0x1f1,
- MachineR4000 = 0x166,
- MachineSh3 = 0x1a2,
- MachineSh3dsp = 0x1a3,
- MachineSh4 = 0x1a6,
- MachineSh5 = 0x1a8,
- MachineThumb = 0x1c2,
- MachineWcemIpsv2 = 0x169
- } MachineType;
-
- ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t file_offset, lldb::offset_t length);
-
- ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP &header_data_sp,
- const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
-
- ~ObjectFilePECOFF() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static ObjectFile *
- CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset, const lldb_private::FileSpec *file,
- lldb::offset_t offset, lldb::offset_t length);
-
- static lldb_private::ObjectFile *CreateMemoryInstance(
- const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
- const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
-
- static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
- lldb::DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool SaveCore(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Status &error);
-
- static bool MagicBytesMatch(lldb::DataBufferSP &data_sp);
-
- static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
-
- bool ParseHeader() override;
-
- bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
- bool value_is_offset) override;
-
- lldb::ByteOrder GetByteOrder() const override;
-
- bool IsExecutable() const override;
-
- uint32_t GetAddressByteSize() const override;
-
- // virtual lldb_private::AddressClass
- // GetAddressClass (lldb::addr_t file_addr);
-
- lldb_private::Symtab *GetSymtab() override;
-
- bool IsStripped() override;
-
- void CreateSections(lldb_private::SectionList &unified_section_list) override;
-
- void Dump(lldb_private::Stream *s) override;
-
- lldb_private::ArchSpec GetArchitecture() override;
-
- bool GetUUID(lldb_private::UUID *uuid) override;
-
- uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
-
- virtual lldb_private::Address GetEntryPointAddress() override;
-
- ObjectFile::Type CalculateType() override;
-
- ObjectFile::Strata CalculateStrata() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- bool IsWindowsSubsystem();
-
- lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
-
-protected:
- bool NeedsEndianSwap() const;
-
- typedef struct dos_header { // DOS .EXE header
- uint16_t e_magic; // Magic number
- uint16_t e_cblp; // Bytes on last page of file
- uint16_t e_cp; // Pages in file
- uint16_t e_crlc; // Relocations
- uint16_t e_cparhdr; // Size of header in paragraphs
- uint16_t e_minalloc; // Minimum extra paragraphs needed
- uint16_t e_maxalloc; // Maximum extra paragraphs needed
- uint16_t e_ss; // Initial (relative) SS value
- uint16_t e_sp; // Initial SP value
- uint16_t e_csum; // Checksum
- uint16_t e_ip; // Initial IP value
- uint16_t e_cs; // Initial (relative) CS value
- uint16_t e_lfarlc; // File address of relocation table
- uint16_t e_ovno; // Overlay number
- uint16_t e_res[4]; // Reserved words
- uint16_t e_oemid; // OEM identifier (for e_oeminfo)
- uint16_t e_oeminfo; // OEM information; e_oemid specific
- uint16_t e_res2[10]; // Reserved words
- uint32_t e_lfanew; // File address of new exe header
- } dos_header_t;
-
- typedef struct coff_header {
- uint16_t machine;
- uint16_t nsects;
- uint32_t modtime;
- uint32_t symoff;
- uint32_t nsyms;
- uint16_t hdrsize;
- uint16_t flags;
- } coff_header_t;
-
- typedef struct data_directory {
- uint32_t vmaddr;
- uint32_t vmsize;
- } data_directory_t;
-
- typedef struct coff_opt_header {
- uint16_t magic;
- uint8_t major_linker_version;
- uint8_t minor_linker_version;
- uint32_t code_size;
- uint32_t data_size;
- uint32_t bss_size;
- uint32_t entry;
- uint32_t code_offset;
- uint32_t data_offset;
-
- uint64_t image_base;
- uint32_t sect_alignment;
- uint32_t file_alignment;
- uint16_t major_os_system_version;
- uint16_t minor_os_system_version;
- uint16_t major_image_version;
- uint16_t minor_image_version;
- uint16_t major_subsystem_version;
- uint16_t minor_subsystem_version;
- uint32_t reserved1;
- uint32_t image_size;
- uint32_t header_size;
- uint32_t checksum;
- uint16_t subsystem;
- uint16_t dll_flags;
- uint64_t stack_reserve_size;
- uint64_t stack_commit_size;
- uint64_t heap_reserve_size;
- uint64_t heap_commit_size;
- uint32_t loader_flags;
- // uint32_t num_data_dir_entries;
- std::vector<data_directory>
- data_dirs; // will contain num_data_dir_entries entries
- } coff_opt_header_t;
-
- typedef enum coff_data_dir_type {
- coff_data_dir_export_table = 0,
- coff_data_dir_import_table = 1,
- } coff_data_dir_type;
-
- typedef struct section_header {
- char name[8];
- uint32_t vmsize; // Virtual Size
- uint32_t vmaddr; // Virtual Addr
- uint32_t size; // File size
- uint32_t offset; // File offset
- uint32_t reloff; // Offset to relocations
- uint32_t lineoff; // Offset to line table entries
- uint16_t nreloc; // Number of relocation entries
- uint16_t nline; // Number of line table entries
- uint32_t flags;
- } section_header_t;
-
- typedef struct coff_symbol {
- char name[8];
- uint32_t value;
- uint16_t sect;
- uint16_t type;
- uint8_t storage;
- uint8_t naux;
- } coff_symbol_t;
-
- typedef struct export_directory_entry {
- uint32_t characteristics;
- uint32_t time_date_stamp;
- uint16_t major_version;
- uint16_t minor_version;
- uint32_t name;
- uint32_t base;
- uint32_t number_of_functions;
- uint32_t number_of_names;
- uint32_t address_of_functions;
- uint32_t address_of_names;
- uint32_t address_of_name_ordinals;
- } export_directory_entry;
-
- static bool ParseDOSHeader(lldb_private::DataExtractor &data,
- dos_header_t &dos_header);
- static bool ParseCOFFHeader(lldb_private::DataExtractor &data,
- lldb::offset_t *offset_ptr,
- coff_header_t &coff_header);
- bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
- bool ParseSectionHeaders(uint32_t offset);
-
- uint32_t ParseDependentModules();
-
- static void DumpDOSHeader(lldb_private::Stream *s,
- const dos_header_t &header);
- static void DumpCOFFHeader(lldb_private::Stream *s,
- const coff_header_t &header);
- static void DumpOptCOFFHeader(lldb_private::Stream *s,
- const coff_opt_header_t &header);
- void DumpSectionHeaders(lldb_private::Stream *s);
- void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh);
- void DumpDependentModules(lldb_private::Stream *s);
-
- llvm::StringRef GetSectionName(const section_header_t &sect);
-
- typedef std::vector<section_header_t> SectionHeaderColl;
- typedef SectionHeaderColl::iterator SectionHeaderCollIter;
- typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
-
-private:
- bool CreateBinary();
-
-private:
- dos_header_t m_dos_header;
- coff_header_t m_coff_header;
- coff_opt_header_t m_coff_header_opt;
- SectionHeaderColl m_sect_headers;
- lldb::addr_t m_image_base;
- lldb_private::Address m_entry_point_address;
- llvm::Optional<lldb_private::FileSpecList> m_deps_filespec;
- typedef llvm::object::OwningBinary<llvm::object::Binary> OWNBINType;
- llvm::Optional<OWNBINType> m_owningbin;
-};
-
-#endif // liblldb_ObjectFilePECOFF_h_
diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
deleted file mode 100644
index e77888c871b55..0000000000000
--- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- WindowsMiniDump.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This function is separated out from ObjectFilePECOFF.cpp to name avoid name
-// collisions with WinAPI preprocessor macros.
-
-#include "WindowsMiniDump.h"
-#include "lldb/Utility/FileSpec.h"
-#include "llvm/Support/ConvertUTF.h"
-
-#ifdef _WIN32
-#include "lldb/Host/windows/windows.h"
-#include <dbghelp.h>
-#endif
-
-namespace lldb_private {
-
-bool SaveMiniDump(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Status &error) {
- if (!process_sp)
- return false;
-#ifdef _WIN32
- HANDLE process_handle = ::OpenProcess(
- PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_sp->GetID());
- const std::string file_name = outfile.GetCString();
- std::wstring wide_name;
- wide_name.resize(file_name.size() + 1);
- char *result_ptr = reinterpret_cast<char *>(&wide_name[0]);
- const llvm::UTF8 *error_ptr = nullptr;
- if (!llvm::ConvertUTF8toWide(sizeof(wchar_t), file_name, result_ptr,
- error_ptr)) {
- error.SetErrorString("cannot convert file name");
- return false;
- }
- HANDLE file_handle =
- ::CreateFileW(wide_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- const auto result =
- ::MiniDumpWriteDump(process_handle, process_sp->GetID(), file_handle,
- MiniDumpWithFullMemoryInfo, NULL, NULL, NULL);
- ::CloseHandle(file_handle);
- ::CloseHandle(process_handle);
- if (!result) {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return false;
- }
- return true;
-#endif
- return false;
-}
-
-} // namesapce lldb_private
diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h
deleted file mode 100644
index 135d533873876..0000000000000
--- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//===-- WindowsMiniDump.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_WindowsMiniDump_h_
-#define liblldb_WindowsMiniDump_h_
-
-#include "lldb/Target/Process.h"
-
-namespace lldb_private {
-
-bool SaveMiniDump(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Status &error);
-
-} // namespace lldb_private
-
-#endif
diff --git a/source/Plugins/OperatingSystem/CMakeLists.txt b/source/Plugins/OperatingSystem/CMakeLists.txt
deleted file mode 100644
index 655007a0aab9e..0000000000000
--- a/source/Plugins/OperatingSystem/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(Python)
diff --git a/source/Plugins/OperatingSystem/Python/CMakeLists.txt b/source/Plugins/OperatingSystem/Python/CMakeLists.txt
deleted file mode 100644
index e8b0f31d37363..0000000000000
--- a/source/Plugins/OperatingSystem/Python/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginOSPython PLUGIN
- OperatingSystemPython.cpp
-
- LINK_LIBS
- lldbCore
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/Platform/Android/AdbClient.cpp b/source/Plugins/Platform/Android/AdbClient.cpp
deleted file mode 100644
index 0ad30a528954b..0000000000000
--- a/source/Plugins/Platform/Android/AdbClient.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-//===-- AdbClient.cpp -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AdbClient.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/FileUtilities.h"
-
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/PosixApi.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataEncoder.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timeout.h"
-
-#include <limits.h>
-
-#include <algorithm>
-#include <cstdlib>
-#include <fstream>
-#include <sstream>
-
-// On Windows, transitive dependencies pull in <Windows.h>, which defines a
-// macro that clashes with a method name.
-#ifdef SendMessage
-#undef SendMessage
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::platform_android;
-using namespace std::chrono;
-
-namespace {
-
-const seconds kReadTimeout(20);
-const char *kOKAY = "OKAY";
-const char *kFAIL = "FAIL";
-const char *kDATA = "DATA";
-const char *kDONE = "DONE";
-
-const char *kSEND = "SEND";
-const char *kRECV = "RECV";
-const char *kSTAT = "STAT";
-
-const size_t kSyncPacketLen = 8;
-// Maximum size of a filesync DATA packet.
-const size_t kMaxPushData = 2 * 1024;
-// Default mode for pushed files.
-const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG
-
-const char *kSocketNamespaceAbstract = "localabstract";
-const char *kSocketNamespaceFileSystem = "localfilesystem";
-
-Status ReadAllBytes(Connection &conn, void *buffer, size_t size) {
-
- Status error;
- ConnectionStatus status;
- char *read_buffer = static_cast<char *>(buffer);
-
- auto now = steady_clock::now();
- const auto deadline = now + kReadTimeout;
- size_t total_read_bytes = 0;
- while (total_read_bytes < size && now < deadline) {
- auto read_bytes =
- conn.Read(read_buffer + total_read_bytes, size - total_read_bytes,
- duration_cast<microseconds>(deadline - now), status, &error);
- if (error.Fail())
- return error;
- total_read_bytes += read_bytes;
- if (status != eConnectionStatusSuccess)
- break;
- now = steady_clock::now();
- }
- if (total_read_bytes < size)
- error = Status(
- "Unable to read requested number of bytes. Connection status: %d.",
- status);
- return error;
-}
-
-} // namespace
-
-Status AdbClient::CreateByDeviceID(const std::string &device_id,
- AdbClient &adb) {
- DeviceIDList connect_devices;
- auto error = adb.GetDevices(connect_devices);
- if (error.Fail())
- return error;
-
- std::string android_serial;
- if (!device_id.empty())
- android_serial = device_id;
- else if (const char *env_serial = std::getenv("ANDROID_SERIAL"))
- android_serial = env_serial;
-
- if (android_serial.empty()) {
- if (connect_devices.size() != 1)
- return Status("Expected a single connected device, got instead %zu - try "
- "setting 'ANDROID_SERIAL'",
- connect_devices.size());
- adb.SetDeviceID(connect_devices.front());
- } else {
- auto find_it = std::find(connect_devices.begin(), connect_devices.end(),
- android_serial);
- if (find_it == connect_devices.end())
- return Status("Device \"%s\" not found", android_serial.c_str());
-
- adb.SetDeviceID(*find_it);
- }
- return error;
-}
-
-AdbClient::AdbClient() {}
-
-AdbClient::AdbClient(const std::string &device_id) : m_device_id(device_id) {}
-
-AdbClient::~AdbClient() {}
-
-void AdbClient::SetDeviceID(const std::string &device_id) {
- m_device_id = device_id;
-}
-
-const std::string &AdbClient::GetDeviceID() const { return m_device_id; }
-
-Status AdbClient::Connect() {
- Status error;
- m_conn.reset(new ConnectionFileDescriptor);
- m_conn->Connect("connect://localhost:5037", &error);
-
- return error;
-}
-
-Status AdbClient::GetDevices(DeviceIDList &device_list) {
- device_list.clear();
-
- auto error = SendMessage("host:devices");
- if (error.Fail())
- return error;
-
- error = ReadResponseStatus();
- if (error.Fail())
- return error;
-
- std::vector<char> in_buffer;
- error = ReadMessage(in_buffer);
-
- llvm::StringRef response(&in_buffer[0], in_buffer.size());
- llvm::SmallVector<llvm::StringRef, 4> devices;
- response.split(devices, "\n", -1, false);
-
- for (const auto device : devices)
- device_list.push_back(device.split('\t').first);
-
- // Force disconnect since ADB closes connection after host:devices response
- // is sent.
- m_conn.reset();
- return error;
-}
-
-Status AdbClient::SetPortForwarding(const uint16_t local_port,
- const uint16_t remote_port) {
- char message[48];
- snprintf(message, sizeof(message), "forward:tcp:%d;tcp:%d", local_port,
- remote_port);
-
- const auto error = SendDeviceMessage(message);
- if (error.Fail())
- return error;
-
- return ReadResponseStatus();
-}
-
-Status
-AdbClient::SetPortForwarding(const uint16_t local_port,
- llvm::StringRef remote_socket_name,
- const UnixSocketNamespace socket_namespace) {
- char message[PATH_MAX];
- const char *sock_namespace_str =
- (socket_namespace == UnixSocketNamespaceAbstract)
- ? kSocketNamespaceAbstract
- : kSocketNamespaceFileSystem;
- snprintf(message, sizeof(message), "forward:tcp:%d;%s:%s", local_port,
- sock_namespace_str, remote_socket_name.str().c_str());
-
- const auto error = SendDeviceMessage(message);
- if (error.Fail())
- return error;
-
- return ReadResponseStatus();
-}
-
-Status AdbClient::DeletePortForwarding(const uint16_t local_port) {
- char message[32];
- snprintf(message, sizeof(message), "killforward:tcp:%d", local_port);
-
- const auto error = SendDeviceMessage(message);
- if (error.Fail())
- return error;
-
- return ReadResponseStatus();
-}
-
-Status AdbClient::SendMessage(const std::string &packet, const bool reconnect) {
- Status error;
- if (!m_conn || reconnect) {
- error = Connect();
- if (error.Fail())
- return error;
- }
-
- char length_buffer[5];
- snprintf(length_buffer, sizeof(length_buffer), "%04x",
- static_cast<int>(packet.size()));
-
- ConnectionStatus status;
-
- m_conn->Write(length_buffer, 4, status, &error);
- if (error.Fail())
- return error;
-
- m_conn->Write(packet.c_str(), packet.size(), status, &error);
- return error;
-}
-
-Status AdbClient::SendDeviceMessage(const std::string &packet) {
- std::ostringstream msg;
- msg << "host-serial:" << m_device_id << ":" << packet;
- return SendMessage(msg.str());
-}
-
-Status AdbClient::ReadMessage(std::vector<char> &message) {
- message.clear();
-
- char buffer[5];
- buffer[4] = 0;
-
- auto error = ReadAllBytes(buffer, 4);
- if (error.Fail())
- return error;
-
- unsigned int packet_len = 0;
- sscanf(buffer, "%x", &packet_len);
-
- message.resize(packet_len, 0);
- error = ReadAllBytes(&message[0], packet_len);
- if (error.Fail())
- message.clear();
-
- return error;
-}
-
-Status AdbClient::ReadMessageStream(std::vector<char> &message,
- milliseconds timeout) {
- auto start = steady_clock::now();
- message.clear();
-
- Status error;
- lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess;
- char buffer[1024];
- while (error.Success() && status == lldb::eConnectionStatusSuccess) {
- auto end = steady_clock::now();
- auto elapsed = end - start;
- if (elapsed >= timeout)
- return Status("Timed out");
-
- size_t n = m_conn->Read(buffer, sizeof(buffer),
- duration_cast<microseconds>(timeout - elapsed),
- status, &error);
- if (n > 0)
- message.insert(message.end(), &buffer[0], &buffer[n]);
- }
- return error;
-}
-
-Status AdbClient::ReadResponseStatus() {
- char response_id[5];
-
- static const size_t packet_len = 4;
- response_id[packet_len] = 0;
-
- auto error = ReadAllBytes(response_id, packet_len);
- if (error.Fail())
- return error;
-
- if (strncmp(response_id, kOKAY, packet_len) != 0)
- return GetResponseError(response_id);
-
- return error;
-}
-
-Status AdbClient::GetResponseError(const char *response_id) {
- if (strcmp(response_id, kFAIL) != 0)
- return Status("Got unexpected response id from adb: \"%s\"", response_id);
-
- std::vector<char> error_message;
- auto error = ReadMessage(error_message);
- if (error.Success())
- error.SetErrorString(
- std::string(&error_message[0], error_message.size()).c_str());
-
- return error;
-}
-
-Status AdbClient::SwitchDeviceTransport() {
- std::ostringstream msg;
- msg << "host:transport:" << m_device_id;
-
- auto error = SendMessage(msg.str());
- if (error.Fail())
- return error;
-
- return ReadResponseStatus();
-}
-
-Status AdbClient::StartSync() {
- auto error = SwitchDeviceTransport();
- if (error.Fail())
- return Status("Failed to switch to device transport: %s",
- error.AsCString());
-
- error = Sync();
- if (error.Fail())
- return Status("Sync failed: %s", error.AsCString());
-
- return error;
-}
-
-Status AdbClient::Sync() {
- auto error = SendMessage("sync:", false);
- if (error.Fail())
- return error;
-
- return ReadResponseStatus();
-}
-
-Status AdbClient::ReadAllBytes(void *buffer, size_t size) {
- return ::ReadAllBytes(*m_conn, buffer, size);
-}
-
-Status AdbClient::internalShell(const char *command, milliseconds timeout,
- std::vector<char> &output_buf) {
- output_buf.clear();
-
- auto error = SwitchDeviceTransport();
- if (error.Fail())
- return Status("Failed to switch to device transport: %s",
- error.AsCString());
-
- StreamString adb_command;
- adb_command.Printf("shell:%s", command);
- error = SendMessage(adb_command.GetString(), false);
- if (error.Fail())
- return error;
-
- error = ReadResponseStatus();
- if (error.Fail())
- return error;
-
- error = ReadMessageStream(output_buf, timeout);
- if (error.Fail())
- return error;
-
- // ADB doesn't propagate return code of shell execution - if
- // output starts with /system/bin/sh: most likely command failed.
- static const char *kShellPrefix = "/system/bin/sh:";
- if (output_buf.size() > strlen(kShellPrefix)) {
- if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix)))
- return Status("Shell command %s failed: %s", command,
- std::string(output_buf.begin(), output_buf.end()).c_str());
- }
-
- return Status();
-}
-
-Status AdbClient::Shell(const char *command, milliseconds timeout,
- std::string *output) {
- std::vector<char> output_buffer;
- auto error = internalShell(command, timeout, output_buffer);
- if (error.Fail())
- return error;
-
- if (output)
- output->assign(output_buffer.begin(), output_buffer.end());
- return error;
-}
-
-Status AdbClient::ShellToFile(const char *command, milliseconds timeout,
- const FileSpec &output_file_spec) {
- std::vector<char> output_buffer;
- auto error = internalShell(command, timeout, output_buffer);
- if (error.Fail())
- return error;
-
- const auto output_filename = output_file_spec.GetPath();
- std::error_code EC;
- llvm::raw_fd_ostream dst(output_filename, EC, llvm::sys::fs::F_None);
- if (EC)
- return Status("Unable to open local file %s", output_filename.c_str());
-
- dst.write(&output_buffer[0], output_buffer.size());
- dst.close();
- if (dst.has_error())
- return Status("Failed to write file %s", output_filename.c_str());
- return Status();
-}
-
-std::unique_ptr<AdbClient::SyncService>
-AdbClient::GetSyncService(Status &error) {
- std::unique_ptr<SyncService> sync_service;
- error = StartSync();
- if (error.Success())
- sync_service.reset(new SyncService(std::move(m_conn)));
-
- return sync_service;
-}
-
-Status AdbClient::SyncService::internalPullFile(const FileSpec &remote_file,
- const FileSpec &local_file) {
- const auto local_file_path = local_file.GetPath();
- llvm::FileRemover local_file_remover(local_file_path);
-
- std::error_code EC;
- llvm::raw_fd_ostream dst(local_file_path, EC, llvm::sys::fs::F_None);
- if (EC)
- return Status("Unable to open local file %s", local_file_path.c_str());
-
- const auto remote_file_path = remote_file.GetPath(false);
- auto error = SendSyncRequest(kRECV, remote_file_path.length(),
- remote_file_path.c_str());
- if (error.Fail())
- return error;
-
- std::vector<char> chunk;
- bool eof = false;
- while (!eof) {
- error = PullFileChunk(chunk, eof);
- if (error.Fail())
- return error;
- if (!eof)
- dst.write(&chunk[0], chunk.size());
- }
- dst.close();
- if (dst.has_error())
- return Status("Failed to write file %s", local_file_path.c_str());
-
- local_file_remover.releaseFile();
- return error;
-}
-
-Status AdbClient::SyncService::internalPushFile(const FileSpec &local_file,
- const FileSpec &remote_file) {
- const auto local_file_path(local_file.GetPath());
- std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary);
- if (!src.is_open())
- return Status("Unable to open local file %s", local_file_path.c_str());
-
- std::stringstream file_description;
- file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode;
- std::string file_description_str = file_description.str();
- auto error = SendSyncRequest(kSEND, file_description_str.length(),
- file_description_str.c_str());
- if (error.Fail())
- return error;
-
- char chunk[kMaxPushData];
- while (!src.eof() && !src.read(chunk, kMaxPushData).bad()) {
- size_t chunk_size = src.gcount();
- error = SendSyncRequest(kDATA, chunk_size, chunk);
- if (error.Fail())
- return Status("Failed to send file chunk: %s", error.AsCString());
- }
- error = SendSyncRequest(
- kDONE, llvm::sys::toTimeT(FileSystem::Instance().GetModificationTime(local_file)),
- nullptr);
- if (error.Fail())
- return error;
-
- std::string response_id;
- uint32_t data_len;
- error = ReadSyncHeader(response_id, data_len);
- if (error.Fail())
- return Status("Failed to read DONE response: %s", error.AsCString());
- if (response_id == kFAIL) {
- std::string error_message(data_len, 0);
- error = ReadAllBytes(&error_message[0], data_len);
- if (error.Fail())
- return Status("Failed to read DONE error message: %s", error.AsCString());
- return Status("Failed to push file: %s", error_message.c_str());
- } else if (response_id != kOKAY)
- return Status("Got unexpected DONE response: %s", response_id.c_str());
-
- // If there was an error reading the source file, finish the adb file
- // transfer first so that adb isn't expecting any more data.
- if (src.bad())
- return Status("Failed read on %s", local_file_path.c_str());
- return error;
-}
-
-Status AdbClient::SyncService::internalStat(const FileSpec &remote_file,
- uint32_t &mode, uint32_t &size,
- uint32_t &mtime) {
- const std::string remote_file_path(remote_file.GetPath(false));
- auto error = SendSyncRequest(kSTAT, remote_file_path.length(),
- remote_file_path.c_str());
- if (error.Fail())
- return Status("Failed to send request: %s", error.AsCString());
-
- static const size_t stat_len = strlen(kSTAT);
- static const size_t response_len = stat_len + (sizeof(uint32_t) * 3);
-
- std::vector<char> buffer(response_len);
- error = ReadAllBytes(&buffer[0], buffer.size());
- if (error.Fail())
- return Status("Failed to read response: %s", error.AsCString());
-
- DataExtractor extractor(&buffer[0], buffer.size(), eByteOrderLittle,
- sizeof(void *));
- offset_t offset = 0;
-
- const void *command = extractor.GetData(&offset, stat_len);
- if (!command)
- return Status("Failed to get response command");
- const char *command_str = static_cast<const char *>(command);
- if (strncmp(command_str, kSTAT, stat_len))
- return Status("Got invalid stat command: %s", command_str);
-
- mode = extractor.GetU32(&offset);
- size = extractor.GetU32(&offset);
- mtime = extractor.GetU32(&offset);
- return Status();
-}
-
-Status AdbClient::SyncService::PullFile(const FileSpec &remote_file,
- const FileSpec &local_file) {
- return executeCommand([this, &remote_file, &local_file]() {
- return internalPullFile(remote_file, local_file);
- });
-}
-
-Status AdbClient::SyncService::PushFile(const FileSpec &local_file,
- const FileSpec &remote_file) {
- return executeCommand([this, &local_file, &remote_file]() {
- return internalPushFile(local_file, remote_file);
- });
-}
-
-Status AdbClient::SyncService::Stat(const FileSpec &remote_file, uint32_t &mode,
- uint32_t &size, uint32_t &mtime) {
- return executeCommand([this, &remote_file, &mode, &size, &mtime]() {
- return internalStat(remote_file, mode, size, mtime);
- });
-}
-
-bool AdbClient::SyncService::IsConnected() const {
- return m_conn && m_conn->IsConnected();
-}
-
-AdbClient::SyncService::SyncService(std::unique_ptr<Connection> &&conn)
- : m_conn(std::move(conn)) {}
-
-Status
-AdbClient::SyncService::executeCommand(const std::function<Status()> &cmd) {
- if (!m_conn)
- return Status("SyncService is disconnected");
-
- const auto error = cmd();
- if (error.Fail())
- m_conn.reset();
-
- return error;
-}
-
-AdbClient::SyncService::~SyncService() {}
-
-Status AdbClient::SyncService::SendSyncRequest(const char *request_id,
- const uint32_t data_len,
- const void *data) {
- const DataBufferSP data_sp(new DataBufferHeap(kSyncPacketLen, 0));
- DataEncoder encoder(data_sp, eByteOrderLittle, sizeof(void *));
- auto offset = encoder.PutData(0, request_id, strlen(request_id));
- encoder.PutU32(offset, data_len);
-
- Status error;
- ConnectionStatus status;
- m_conn->Write(data_sp->GetBytes(), kSyncPacketLen, status, &error);
- if (error.Fail())
- return error;
-
- if (data)
- m_conn->Write(data, data_len, status, &error);
- return error;
-}
-
-Status AdbClient::SyncService::ReadSyncHeader(std::string &response_id,
- uint32_t &data_len) {
- char buffer[kSyncPacketLen];
-
- auto error = ReadAllBytes(buffer, kSyncPacketLen);
- if (error.Success()) {
- response_id.assign(&buffer[0], 4);
- DataExtractor extractor(&buffer[4], 4, eByteOrderLittle, sizeof(void *));
- offset_t offset = 0;
- data_len = extractor.GetU32(&offset);
- }
-
- return error;
-}
-
-Status AdbClient::SyncService::PullFileChunk(std::vector<char> &buffer,
- bool &eof) {
- buffer.clear();
-
- std::string response_id;
- uint32_t data_len;
- auto error = ReadSyncHeader(response_id, data_len);
- if (error.Fail())
- return error;
-
- if (response_id == kDATA) {
- buffer.resize(data_len, 0);
- error = ReadAllBytes(&buffer[0], data_len);
- if (error.Fail())
- buffer.clear();
- } else if (response_id == kDONE) {
- eof = true;
- } else if (response_id == kFAIL) {
- std::string error_message(data_len, 0);
- error = ReadAllBytes(&error_message[0], data_len);
- if (error.Fail())
- return Status("Failed to read pull error message: %s", error.AsCString());
- return Status("Failed to pull file: %s", error_message.c_str());
- } else
- return Status("Pull failed with unknown response: %s", response_id.c_str());
-
- return Status();
-}
-
-Status AdbClient::SyncService::ReadAllBytes(void *buffer, size_t size) {
- return ::ReadAllBytes(*m_conn, buffer, size);
-}
diff --git a/source/Plugins/Platform/Android/AdbClient.h b/source/Plugins/Platform/Android/AdbClient.h
deleted file mode 100644
index 0d2100fc5663b..0000000000000
--- a/source/Plugins/Platform/Android/AdbClient.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//===-- AdbClient.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_AdbClient_h_
-#define liblldb_AdbClient_h_
-
-#include "lldb/Utility/Status.h"
-#include <chrono>
-#include <functional>
-#include <list>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace lldb_private {
-
-class FileSpec;
-
-namespace platform_android {
-
-class AdbClient {
-public:
- enum UnixSocketNamespace {
- UnixSocketNamespaceAbstract,
- UnixSocketNamespaceFileSystem,
- };
-
- using DeviceIDList = std::list<std::string>;
-
- class SyncService {
- friend class AdbClient;
-
- public:
- ~SyncService();
-
- Status PullFile(const FileSpec &remote_file, const FileSpec &local_file);
-
- Status PushFile(const FileSpec &local_file, const FileSpec &remote_file);
-
- Status Stat(const FileSpec &remote_file, uint32_t &mode, uint32_t &size,
- uint32_t &mtime);
-
- bool IsConnected() const;
-
- private:
- explicit SyncService(std::unique_ptr<Connection> &&conn);
-
- Status SendSyncRequest(const char *request_id, const uint32_t data_len,
- const void *data);
-
- Status ReadSyncHeader(std::string &response_id, uint32_t &data_len);
-
- Status PullFileChunk(std::vector<char> &buffer, bool &eof);
-
- Status ReadAllBytes(void *buffer, size_t size);
-
- Status internalPullFile(const FileSpec &remote_file,
- const FileSpec &local_file);
-
- Status internalPushFile(const FileSpec &local_file,
- const FileSpec &remote_file);
-
- Status internalStat(const FileSpec &remote_file, uint32_t &mode,
- uint32_t &size, uint32_t &mtime);
-
- Status executeCommand(const std::function<Status()> &cmd);
-
- std::unique_ptr<Connection> m_conn;
- };
-
- static Status CreateByDeviceID(const std::string &device_id, AdbClient &adb);
-
- AdbClient();
- explicit AdbClient(const std::string &device_id);
-
- ~AdbClient();
-
- const std::string &GetDeviceID() const;
-
- Status GetDevices(DeviceIDList &device_list);
-
- Status SetPortForwarding(const uint16_t local_port,
- const uint16_t remote_port);
-
- Status SetPortForwarding(const uint16_t local_port,
- llvm::StringRef remote_socket_name,
- const UnixSocketNamespace socket_namespace);
-
- Status DeletePortForwarding(const uint16_t local_port);
-
- Status Shell(const char *command, std::chrono::milliseconds timeout,
- std::string *output);
-
- Status ShellToFile(const char *command, std::chrono::milliseconds timeout,
- const FileSpec &output_file_spec);
-
- std::unique_ptr<SyncService> GetSyncService(Status &error);
-
- Status SwitchDeviceTransport();
-
-private:
- Status Connect();
-
- void SetDeviceID(const std::string &device_id);
-
- Status SendMessage(const std::string &packet, const bool reconnect = true);
-
- Status SendDeviceMessage(const std::string &packet);
-
- Status ReadMessage(std::vector<char> &message);
-
- Status ReadMessageStream(std::vector<char> &message,
- std::chrono::milliseconds timeout);
-
- Status GetResponseError(const char *response_id);
-
- Status ReadResponseStatus();
-
- Status Sync();
-
- Status StartSync();
-
- Status internalShell(const char *command, std::chrono::milliseconds timeout,
- std::vector<char> &output_buf);
-
- Status ReadAllBytes(void *buffer, size_t size);
-
- std::string m_device_id;
- std::unique_ptr<Connection> m_conn;
-};
-
-} // namespace platform_android
-} // namespace lldb_private
-
-#endif // liblldb_AdbClient_h_
diff --git a/source/Plugins/Platform/Android/CMakeLists.txt b/source/Plugins/Platform/Android/CMakeLists.txt
deleted file mode 100644
index 5abb51a0b94ac..0000000000000
--- a/source/Plugins/Platform/Android/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginPlatformAndroid PLUGIN
- AdbClient.cpp
- PlatformAndroid.cpp
- PlatformAndroidRemoteGDBServer.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbPluginPlatformLinux
- lldbPluginPlatformGDB
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
deleted file mode 100644
index a56ab0e301534..0000000000000
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-//===-- PlatformAndroid.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/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/StringConvert.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Scalar.h"
-#include "lldb/Utility/UriParser.h"
-
-#include "AdbClient.h"
-#include "PlatformAndroid.h"
-#include "PlatformAndroidRemoteGDBServer.h"
-#include "lldb/Target/Target.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::platform_android;
-using namespace std::chrono;
-
-static uint32_t g_initialize_count = 0;
-static const unsigned int g_android_default_cache_size =
- 2048; // Fits inside 4k adb packet.
-
-void PlatformAndroid::Initialize() {
- PlatformLinux::Initialize();
-
- if (g_initialize_count++ == 0) {
-#if defined(__ANDROID__)
- PlatformSP default_platform_sp(new PlatformAndroid(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform(default_platform_sp);
-#endif
- PluginManager::RegisterPlugin(
- PlatformAndroid::GetPluginNameStatic(false),
- PlatformAndroid::GetPluginDescriptionStatic(false),
- PlatformAndroid::CreateInstance);
- }
-}
-
-void PlatformAndroid::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformAndroid::CreateInstance);
- }
- }
-
- PlatformLinux::Terminate();
-}
-
-PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformAndroid::%s(force=%s, arch={%s,%s})", __FUNCTION__,
- force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::PC:
- create = true;
- break;
-
-#if defined(__ANDROID__)
- // Only accept "unknown" for the vendor if the host is android and if
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified).
- case llvm::Triple::VendorType::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-#endif
- default:
- break;
- }
-
- if (create) {
- switch (triple.getEnvironment()) {
- case llvm::Triple::Android:
- break;
-
-#if defined(__ANDROID__)
- // Only accept "unknown" for the OS if the host is android and it
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::EnvironmentType::UnknownEnvironment:
- create = !arch->TripleEnvironmentWasSpecified();
- break;
-#endif
- default:
- create = false;
- break;
- }
- }
- }
-
- if (create) {
- if (log)
- log->Printf("PlatformAndroid::%s() creating remote-android platform",
- __FUNCTION__);
- return PlatformSP(new PlatformAndroid(false));
- }
-
- if (log)
- log->Printf(
- "PlatformAndroid::%s() aborting creation of remote-android platform",
- __FUNCTION__);
-
- return PlatformSP();
-}
-
-PlatformAndroid::PlatformAndroid(bool is_host)
- : PlatformLinux(is_host), m_sdk_version(0) {}
-
-PlatformAndroid::~PlatformAndroid() {}
-
-ConstString PlatformAndroid::GetPluginNameStatic(bool is_host) {
- if (is_host) {
- static ConstString g_host_name(Platform::GetHostPlatformName());
- return g_host_name;
- } else {
- static ConstString g_remote_name("remote-android");
- return g_remote_name;
- }
-}
-
-const char *PlatformAndroid::GetPluginDescriptionStatic(bool is_host) {
- if (is_host)
- return "Local Android user platform plug-in.";
- else
- return "Remote Android user platform plug-in.";
-}
-
-ConstString PlatformAndroid::GetPluginName() {
- return GetPluginNameStatic(IsHost());
-}
-
-Status PlatformAndroid::ConnectRemote(Args &args) {
- m_device_id.clear();
-
- if (IsHost()) {
- return Status("can't connect to the host platform '%s', always connected",
- GetPluginName().GetCString());
- }
-
- if (!m_remote_platform_sp)
- m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer());
-
- int port;
- llvm::StringRef scheme, host, path;
- const char *url = args.GetArgumentAtIndex(0);
- if (!url)
- return Status("URL is null.");
- if (!UriParser::Parse(url, scheme, host, port, path))
- return Status("Invalid URL: %s", url);
- if (host != "localhost")
- m_device_id = host;
-
- auto error = PlatformLinux::ConnectRemote(args);
- if (error.Success()) {
- AdbClient adb;
- error = AdbClient::CreateByDeviceID(m_device_id, adb);
- if (error.Fail())
- return error;
-
- m_device_id = adb.GetDeviceID();
- }
- return error;
-}
-
-Status PlatformAndroid::GetFile(const FileSpec &source,
- const FileSpec &destination) {
- if (IsHost() || !m_remote_platform_sp)
- return PlatformLinux::GetFile(source, destination);
-
- FileSpec source_spec(source.GetPath(false), FileSpec::Style::posix);
- if (source_spec.IsRelative())
- source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
- source_spec.GetCString(false));
-
- Status error;
- auto sync_service = GetSyncService(error);
- if (error.Fail())
- return error;
-
- uint32_t mode = 0, size = 0, mtime = 0;
- error = sync_service->Stat(source_spec, mode, size, mtime);
- if (error.Fail())
- return error;
-
- if (mode != 0)
- return sync_service->PullFile(source_spec, destination);
-
- auto source_file = source_spec.GetCString(false);
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Got mode == 0 on '%s': try to get file via 'shell cat'",
- source_file);
-
- if (strchr(source_file, '\'') != nullptr)
- return Status("Doesn't support single-quotes in filenames");
-
- // mode == 0 can signify that adbd cannot access the file due security
- // constraints - try "cat ..." as a fallback.
- AdbClient adb(m_device_id);
-
- char cmd[PATH_MAX];
- snprintf(cmd, sizeof(cmd), "cat '%s'", source_file);
-
- return adb.ShellToFile(cmd, minutes(1), destination);
-}
-
-Status PlatformAndroid::PutFile(const FileSpec &source,
- const FileSpec &destination, uint32_t uid,
- uint32_t gid) {
- if (IsHost() || !m_remote_platform_sp)
- return PlatformLinux::PutFile(source, destination, uid, gid);
-
- FileSpec destination_spec(destination.GetPath(false), FileSpec::Style::posix);
- if (destination_spec.IsRelative())
- destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
- destination_spec.GetCString(false));
-
- // TODO: Set correct uid and gid on remote file.
- Status error;
- auto sync_service = GetSyncService(error);
- if (error.Fail())
- return error;
- return sync_service->PushFile(source, destination_spec);
-}
-
-const char *PlatformAndroid::GetCacheHostname() { return m_device_id.c_str(); }
-
-Status PlatformAndroid::DownloadModuleSlice(const FileSpec &src_file_spec,
- const uint64_t src_offset,
- const uint64_t src_size,
- const FileSpec &dst_file_spec) {
- if (src_offset != 0)
- return Status("Invalid offset - %" PRIu64, src_offset);
-
- return GetFile(src_file_spec, dst_file_spec);
-}
-
-Status PlatformAndroid::DisconnectRemote() {
- Status error = PlatformLinux::DisconnectRemote();
- if (error.Success()) {
- m_device_id.clear();
- m_sdk_version = 0;
- }
- return error;
-}
-
-uint32_t PlatformAndroid::GetDefaultMemoryCacheLineSize() {
- return g_android_default_cache_size;
-}
-
-uint32_t PlatformAndroid::GetSdkVersion() {
- if (!IsConnected())
- return 0;
-
- if (m_sdk_version != 0)
- return m_sdk_version;
-
- std::string version_string;
- AdbClient adb(m_device_id);
- Status error =
- adb.Shell("getprop ro.build.version.sdk", seconds(5), &version_string);
- version_string = llvm::StringRef(version_string).trim().str();
-
- if (error.Fail() || version_string.empty()) {
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("Get SDK version failed. (error: %s, output: %s)",
- error.AsCString(), version_string.c_str());
- return 0;
- }
-
- m_sdk_version = StringConvert::ToUInt32(version_string.c_str());
- return m_sdk_version;
-}
-
-Status PlatformAndroid::DownloadSymbolFile(const lldb::ModuleSP &module_sp,
- const FileSpec &dst_file_spec) {
- // For oat file we can try to fetch additional debug info from the device
- ConstString extension = module_sp->GetFileSpec().GetFileNameExtension();
- if (extension != ConstString(".oat") && extension != ConstString(".odex"))
- return Status(
- "Symbol file downloading only supported for oat and odex files");
-
- // If we have no information about the platform file we can't execute oatdump
- if (!module_sp->GetPlatformFileSpec())
- return Status("No platform file specified");
-
- // Symbolizer isn't available before SDK version 23
- if (GetSdkVersion() < 23)
- return Status("Symbol file generation only supported on SDK 23+");
-
- // If we already have symtab then we don't have to try and generate one
- if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) !=
- nullptr)
- return Status("Symtab already available in the module");
-
- AdbClient adb(m_device_id);
- std::string tmpdir;
- Status error = adb.Shell("mktemp --directory --tmpdir /data/local/tmp",
- seconds(5), &tmpdir);
- if (error.Fail() || tmpdir.empty())
- return Status("Failed to generate temporary directory on the device (%s)",
- error.AsCString());
- tmpdir = llvm::StringRef(tmpdir).trim().str();
-
- // Create file remover for the temporary directory created on the device
- std::unique_ptr<std::string, std::function<void(std::string *)>>
- tmpdir_remover(&tmpdir, [&adb](std::string *s) {
- StreamString command;
- command.Printf("rm -rf %s", s->c_str());
- Status error = adb.Shell(command.GetData(), seconds(5), nullptr);
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log && error.Fail())
- log->Printf("Failed to remove temp directory: %s", error.AsCString());
- });
-
- FileSpec symfile_platform_filespec(tmpdir);
- symfile_platform_filespec.AppendPathComponent("symbolized.oat");
-
- // Execute oatdump on the remote device to generate a file with symtab
- StreamString command;
- command.Printf("oatdump --symbolize=%s --output=%s",
- module_sp->GetPlatformFileSpec().GetCString(false),
- symfile_platform_filespec.GetCString(false));
- error = adb.Shell(command.GetData(), minutes(1), nullptr);
- if (error.Fail())
- return Status("Oatdump failed: %s", error.AsCString());
-
- // Download the symbolfile from the remote device
- return GetFile(symfile_platform_filespec, dst_file_spec);
-}
-
-bool PlatformAndroid::GetRemoteOSVersion() {
- m_os_version = llvm::VersionTuple(GetSdkVersion());
- return !m_os_version.empty();
-}
-
-llvm::StringRef
-PlatformAndroid::GetLibdlFunctionDeclarations(lldb_private::Process *process) {
- SymbolContextList matching_symbols;
- std::vector<const char *> dl_open_names = { "__dl_dlopen", "dlopen" };
- const char *dl_open_name = nullptr;
- Target &target = process->GetTarget();
- for (auto name: dl_open_names) {
- if (target.GetImages().FindFunctionSymbols(ConstString(name),
- eFunctionNameTypeFull,
- matching_symbols)) {
- dl_open_name = name;
- break;
- }
- }
- // Older platform versions have the dl function symbols mangled
- if (dl_open_name == dl_open_names[0])
- return R"(
- extern "C" void* dlopen(const char*, int) asm("__dl_dlopen");
- extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym");
- extern "C" int dlclose(void*) asm("__dl_dlclose");
- extern "C" char* dlerror(void) asm("__dl_dlerror");
- )";
-
- return PlatformPOSIX::GetLibdlFunctionDeclarations(process);
-}
-
-AdbClient::SyncService *PlatformAndroid::GetSyncService(Status &error) {
- if (m_adb_sync_svc && m_adb_sync_svc->IsConnected())
- return m_adb_sync_svc.get();
-
- AdbClient adb(m_device_id);
- m_adb_sync_svc = adb.GetSyncService(error);
- return (error.Success()) ? m_adb_sync_svc.get() : nullptr;
-}
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.h b/source/Plugins/Platform/Android/PlatformAndroid.h
deleted file mode 100644
index 2e7706cc246e0..0000000000000
--- a/source/Plugins/Platform/Android/PlatformAndroid.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===-- PlatformAndroid.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_PlatformAndroid_h_
-#define liblldb_PlatformAndroid_h_
-
-#include <memory>
-#include <string>
-
-#include "Plugins/Platform/Linux/PlatformLinux.h"
-
-#include "AdbClient.h"
-
-namespace lldb_private {
-namespace platform_android {
-
-class PlatformAndroid : public platform_linux::PlatformLinux {
-public:
- PlatformAndroid(bool is_host);
-
- ~PlatformAndroid() override;
-
- static void Initialize();
-
- static void Terminate();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
-
- static ConstString GetPluginNameStatic(bool is_host);
-
- static const char *GetPluginDescriptionStatic(bool is_host);
-
- ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- Status ConnectRemote(Args &args) override;
-
- Status GetFile(const FileSpec &source, const FileSpec &destination) override;
-
- Status PutFile(const FileSpec &source, const FileSpec &destination,
- uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override;
-
- uint32_t GetSdkVersion();
-
- bool GetRemoteOSVersion() override;
-
- Status DisconnectRemote() override;
-
- uint32_t GetDefaultMemoryCacheLineSize() override;
-
-protected:
- const char *GetCacheHostname() override;
-
- Status DownloadModuleSlice(const FileSpec &src_file_spec,
- const uint64_t src_offset, const uint64_t src_size,
- const FileSpec &dst_file_spec) override;
-
- Status DownloadSymbolFile(const lldb::ModuleSP &module_sp,
- const FileSpec &dst_file_spec) override;
-
- llvm::StringRef
- GetLibdlFunctionDeclarations(lldb_private::Process *process) override;
-
-private:
- AdbClient::SyncService *GetSyncService(Status &error);
-
- std::unique_ptr<AdbClient::SyncService> m_adb_sync_svc;
- std::string m_device_id;
- uint32_t m_sdk_version;
-
- DISALLOW_COPY_AND_ASSIGN(PlatformAndroid);
-};
-
-} // namespace platofor_android
-} // namespace lldb_private
-
-#endif // liblldb_PlatformAndroid_h_
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
deleted file mode 100644
index bbb03369d63c6..0000000000000
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-//===-- PlatformAndroidRemoteGDBServer.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/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/UriParser.h"
-
-#include "PlatformAndroidRemoteGDBServer.h"
-
-#include <sstream>
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace platform_android;
-
-static const lldb::pid_t g_remote_platform_pid =
- 0; // Alias for the process id of lldb-platform
-
-static Status ForwardPortWithAdb(
- const uint16_t local_port, const uint16_t remote_port,
- llvm::StringRef remote_socket_name,
- const llvm::Optional<AdbClient::UnixSocketNamespace> &socket_namespace,
- std::string &device_id) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
-
- AdbClient adb;
- auto error = AdbClient::CreateByDeviceID(device_id, adb);
- if (error.Fail())
- return error;
-
- device_id = adb.GetDeviceID();
- if (log)
- log->Printf("Connected to Android device \"%s\"", device_id.c_str());
-
- if (remote_port != 0) {
- if (log)
- log->Printf("Forwarding remote TCP port %d to local TCP port %d",
- remote_port, local_port);
- return adb.SetPortForwarding(local_port, remote_port);
- }
-
- if (log)
- log->Printf("Forwarding remote socket \"%s\" to local TCP port %d",
- remote_socket_name.str().c_str(), local_port);
-
- if (!socket_namespace)
- return Status("Invalid socket namespace");
-
- return adb.SetPortForwarding(local_port, remote_socket_name,
- *socket_namespace);
-}
-
-static Status DeleteForwardPortWithAdb(uint16_t local_port,
- const std::string &device_id) {
- AdbClient adb(device_id);
- return adb.DeletePortForwarding(local_port);
-}
-
-static Status FindUnusedPort(uint16_t &port) {
- Status error;
- std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(true, false));
- if (error.Fail())
- return error;
-
- error = tcp_socket->Listen("127.0.0.1:0", 1);
- if (error.Success())
- port = tcp_socket->GetLocalPortNumber();
-
- return error;
-}
-
-PlatformAndroidRemoteGDBServer::PlatformAndroidRemoteGDBServer() {}
-
-PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer() {
- for (const auto &it : m_port_forwards)
- DeleteForwardPortWithAdb(it.second, m_device_id);
-}
-
-bool PlatformAndroidRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
- std::string &connect_url) {
- uint16_t remote_port = 0;
- std::string socket_name;
- if (!m_gdb_client.LaunchGDBServer("127.0.0.1", pid, remote_port, socket_name))
- return false;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
-
- auto error =
- MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url);
- if (error.Success() && log)
- log->Printf("gdbserver connect URL: %s", connect_url.c_str());
-
- return error.Success();
-}
-
-bool PlatformAndroidRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) {
- DeleteForwardPort(pid);
- return m_gdb_client.KillSpawnedProcess(pid);
-}
-
-Status PlatformAndroidRemoteGDBServer::ConnectRemote(Args &args) {
- m_device_id.clear();
-
- if (args.GetArgumentCount() != 1)
- return Status(
- "\"platform connect\" takes a single argument: <connect-url>");
-
- int remote_port;
- llvm::StringRef scheme, host, path;
- const char *url = args.GetArgumentAtIndex(0);
- if (!url)
- return Status("URL is null.");
- if (!UriParser::Parse(url, scheme, host, remote_port, path))
- return Status("Invalid URL: %s", url);
- if (host != "localhost")
- m_device_id = host;
-
- m_socket_namespace.reset();
- if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME)
- m_socket_namespace = AdbClient::UnixSocketNamespaceFileSystem;
- else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME)
- m_socket_namespace = AdbClient::UnixSocketNamespaceAbstract;
-
- std::string connect_url;
- auto error =
- MakeConnectURL(g_remote_platform_pid, (remote_port < 0) ? 0 : remote_port,
- path, connect_url);
-
- if (error.Fail())
- return error;
-
- args.ReplaceArgumentAtIndex(0, connect_url);
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Rewritten platform connect URL: %s", connect_url.c_str());
-
- error = PlatformRemoteGDBServer::ConnectRemote(args);
- if (error.Fail())
- DeleteForwardPort(g_remote_platform_pid);
-
- return error;
-}
-
-Status PlatformAndroidRemoteGDBServer::DisconnectRemote() {
- DeleteForwardPort(g_remote_platform_pid);
- return PlatformRemoteGDBServer::DisconnectRemote();
-}
-
-void PlatformAndroidRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
-
- auto it = m_port_forwards.find(pid);
- if (it == m_port_forwards.end())
- return;
-
- const auto port = it->second;
- const auto error = DeleteForwardPortWithAdb(port, m_device_id);
- if (error.Fail()) {
- if (log)
- log->Printf("Failed to delete port forwarding (pid=%" PRIu64
- ", port=%d, device=%s): %s",
- pid, port, m_device_id.c_str(), error.AsCString());
- }
- m_port_forwards.erase(it);
-}
-
-Status PlatformAndroidRemoteGDBServer::MakeConnectURL(
- const lldb::pid_t pid, const uint16_t remote_port,
- llvm::StringRef remote_socket_name, std::string &connect_url) {
- static const int kAttempsNum = 5;
-
- Status error;
- // There is a race possibility that somebody will occupy a port while we're
- // in between FindUnusedPort and ForwardPortWithAdb - adding the loop to
- // mitigate such problem.
- for (auto i = 0; i < kAttempsNum; ++i) {
- uint16_t local_port = 0;
- error = FindUnusedPort(local_port);
- if (error.Fail())
- return error;
-
- error = ForwardPortWithAdb(local_port, remote_port, remote_socket_name,
- m_socket_namespace, m_device_id);
- if (error.Success()) {
- m_port_forwards[pid] = local_port;
- std::ostringstream url_str;
- url_str << "connect://localhost:" << local_port;
- connect_url = url_str.str();
- break;
- }
- }
-
- return error;
-}
-
-lldb::ProcessSP PlatformAndroidRemoteGDBServer::ConnectProcess(
- llvm::StringRef connect_url, llvm::StringRef plugin_name,
- lldb_private::Debugger &debugger, lldb_private::Target *target,
- lldb_private::Status &error) {
- // We don't have the pid of the remote gdbserver when it isn't started by us
- // but we still want to store the list of port forwards we set up in our port
- // forward map. Generate a fake pid for these cases what won't collide with
- // any other valid pid on android.
- static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL;
-
- int remote_port;
- llvm::StringRef scheme, host, path;
- if (!UriParser::Parse(connect_url, scheme, host, remote_port, path)) {
- error.SetErrorStringWithFormat("Invalid URL: %s",
- connect_url.str().c_str());
- return nullptr;
- }
-
- std::string new_connect_url;
- error = MakeConnectURL(s_remote_gdbserver_fake_pid--,
- (remote_port < 0) ? 0 : remote_port, path,
- new_connect_url);
- if (error.Fail())
- return nullptr;
-
- return PlatformRemoteGDBServer::ConnectProcess(new_connect_url, plugin_name,
- debugger, target, error);
-}
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
deleted file mode 100644
index 40356293b589a..0000000000000
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//===-- PlatformAndroidRemoteGDBServer.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_PlatformAndroidRemoteGDBServer_h_
-#define liblldb_PlatformAndroidRemoteGDBServer_h_
-
-#include <map>
-#include <utility>
-
-#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
-
-#include "llvm/ADT/Optional.h"
-
-#include "AdbClient.h"
-
-namespace lldb_private {
-namespace platform_android {
-
-class PlatformAndroidRemoteGDBServer
- : public platform_gdb_server::PlatformRemoteGDBServer {
-public:
- PlatformAndroidRemoteGDBServer();
-
- ~PlatformAndroidRemoteGDBServer() override;
-
- Status ConnectRemote(Args &args) override;
-
- Status DisconnectRemote() override;
-
- lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
- llvm::StringRef plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Status &error) override;
-
-protected:
- std::string m_device_id;
- std::map<lldb::pid_t, uint16_t> m_port_forwards;
- llvm::Optional<AdbClient::UnixSocketNamespace> m_socket_namespace;
-
- bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override;
-
- bool KillSpawnedProcess(lldb::pid_t pid) override;
-
- void DeleteForwardPort(lldb::pid_t pid);
-
- Status MakeConnectURL(const lldb::pid_t pid, const uint16_t remote_port,
- llvm::StringRef remote_socket_name,
- std::string &connect_url);
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformAndroidRemoteGDBServer);
-};
-
-} // namespace platform_android
-} // namespace lldb_private
-
-#endif // liblldb_PlatformAndroidRemoteGDBServer_h_
diff --git a/source/Plugins/Platform/CMakeLists.txt b/source/Plugins/Platform/CMakeLists.txt
deleted file mode 100644
index ddb71212ce48d..0000000000000
--- a/source/Plugins/Platform/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-#if (CMAKE_SYSTEM_NAME MATCHES "Linux")
- add_subdirectory(Linux)
-#elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- add_subdirectory(FreeBSD)
-#elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- add_subdirectory(NetBSD)
-#elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
- add_subdirectory(OpenBSD)
-#elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- add_subdirectory(MacOSX)
-#elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
- add_subdirectory(Windows)
-#endif()
-
-add_subdirectory(POSIX)
-add_subdirectory(gdb-server)
-add_subdirectory(Kalimba)
-add_subdirectory(Android)
diff --git a/source/Plugins/Platform/FreeBSD/CMakeLists.txt b/source/Plugins/Platform/FreeBSD/CMakeLists.txt
deleted file mode 100644
index 1c27e1b7adaaa..0000000000000
--- a/source/Plugins/Platform/FreeBSD/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-add_lldb_library(lldbPluginPlatformFreeBSD PLUGIN
- PlatformFreeBSD.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbTarget
- )
diff --git a/source/Plugins/Platform/Kalimba/CMakeLists.txt b/source/Plugins/Platform/Kalimba/CMakeLists.txt
deleted file mode 100644
index 02f1827f9a485..0000000000000
--- a/source/Plugins/Platform/Kalimba/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_lldb_library(lldbPluginPlatformKalimba PLUGIN
- PlatformKalimba.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbTarget
- )
diff --git a/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp b/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
deleted file mode 100644
index cc902b7f7ad52..0000000000000
--- a/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-//===-- PlatformKalimba.cpp ---------------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformKalimba.h"
-#include "lldb/Host/Config.h"
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-static uint32_t g_initialize_count = 0;
-
-PlatformSP PlatformKalimba::CreateInstance(bool force, const ArchSpec *arch) {
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::CSR:
- create = true;
- break;
-
- default:
- break;
- }
- }
- if (create)
- return PlatformSP(new PlatformKalimba(false));
- return PlatformSP();
-}
-
-lldb_private::ConstString
-PlatformKalimba::GetPluginNameStatic(bool /*is_host*/) {
- static ConstString g_remote_name("kalimba");
- return g_remote_name;
-}
-
-const char *PlatformKalimba::GetPluginDescriptionStatic(bool /*is_host*/) {
- return "Kalimba user platform plug-in.";
-}
-
-lldb_private::ConstString PlatformKalimba::GetPluginName() {
- return GetPluginNameStatic(false);
-}
-
-void PlatformKalimba::Initialize() {
- Platform::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(
- PlatformKalimba::GetPluginNameStatic(false),
- PlatformKalimba::GetPluginDescriptionStatic(false),
- PlatformKalimba::CreateInstance);
- }
-}
-
-void PlatformKalimba::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformKalimba::CreateInstance);
- }
- }
-
- Platform::Terminate();
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformKalimba::PlatformKalimba(bool is_host)
- : Platform(is_host), // This is the local host platform
- m_remote_platform_sp() {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformKalimba::~PlatformKalimba() {}
-
-bool PlatformKalimba::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- if (idx == 0) {
- arch = ArchSpec("kalimba3-csr-unknown");
- return true;
- }
- if (idx == 1) {
- arch = ArchSpec("kalimba4-csr-unknown");
- return true;
- }
- if (idx == 2) {
- arch = ArchSpec("kalimba5-csr-unknown");
- return true;
- }
- return false;
-}
-
-void PlatformKalimba::GetStatus(Stream &strm) { Platform::GetStatus(strm); }
-
-size_t
-PlatformKalimba::GetSoftwareBreakpointTrapOpcode(Target & /*target*/,
- BreakpointSite * /*bp_site*/) {
- // the target hardware does not support software breakpoints
- return 0;
-}
-
-Status PlatformKalimba::LaunchProcess(ProcessLaunchInfo &launch_info) {
- Status error;
-
- if (IsHost()) {
- error.SetErrorString("native execution is not possible");
- } else {
- error.SetErrorString("the platform is not currently connected");
- }
- return error;
-}
-
-lldb::ProcessSP PlatformKalimba::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger, Target *target,
- Status &error) {
- lldb::ProcessSP process_sp;
- if (IsHost()) {
- error.SetErrorString("native execution is not possible");
- } else {
- if (m_remote_platform_sp)
- process_sp =
- m_remote_platform_sp->Attach(attach_info, debugger, target, error);
- else
- error.SetErrorString("the platform is not currently connected");
- }
- return process_sp;
-}
-
-void PlatformKalimba::CalculateTrapHandlerSymbolNames() {
- // TODO Research this sometime.
-}
diff --git a/source/Plugins/Platform/Kalimba/PlatformKalimba.h b/source/Plugins/Platform/Kalimba/PlatformKalimba.h
deleted file mode 100644
index efa78457d5859..0000000000000
--- a/source/Plugins/Platform/Kalimba/PlatformKalimba.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- PlatformKalimba.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_PlatformKalimba_h_
-#define liblldb_PlatformKalimba_h_
-
-#include "lldb/Target/Platform.h"
-
-namespace lldb_private {
-
-class PlatformKalimba : public Platform {
-public:
- PlatformKalimba(bool is_host);
-
- ~PlatformKalimba() override;
-
- static void Initialize();
-
- static void Terminate();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static lldb_private::ConstString GetPluginNameStatic(bool is_host);
-
- static const char *GetPluginDescriptionStatic(bool is_host);
-
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- const char *GetDescription() override {
- return GetPluginDescriptionStatic(IsHost());
- }
-
- void GetStatus(Stream &strm) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
-
- size_t GetSoftwareBreakpointTrapOpcode(Target &target,
- BreakpointSite *bp_site) override;
-
- lldb_private::Status
- LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
-
- lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
- Target *target, Status &error) override;
-
- // Kalimba processes can not be launched by spawning and attaching.
- bool CanDebugProcess() override { return false; }
-
- void CalculateTrapHandlerSymbolNames() override;
-
-protected:
- lldb::PlatformSP m_remote_platform_sp;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformKalimba);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_PlatformKalimba_h_
diff --git a/source/Plugins/Platform/Linux/CMakeLists.txt b/source/Plugins/Platform/Linux/CMakeLists.txt
deleted file mode 100644
index bad039d0ad509..0000000000000
--- a/source/Plugins/Platform/Linux/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-add_lldb_library(lldbPluginPlatformLinux PLUGIN
- PlatformLinux.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbInterpreter
- lldbTarget
- lldbPluginPlatformPOSIX
- )
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
deleted file mode 100644
index 7498c648d6e4f..0000000000000
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-//===-- PlatformLinux.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformLinux.h"
-#include "lldb/Host/Config.h"
-
-#include <stdio.h>
-#ifndef LLDB_DISABLE_POSIX
-#include <sys/utsname.h>
-#endif
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-// Define these constants from Linux mman.h for use when targeting remote linux
-// systems even when host has different values.
-#define MAP_PRIVATE 2
-#define MAP_ANON 0x20
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::platform_linux;
-
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-
-PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
- arch ? arch->GetArchitectureName() : "<null>",
- arch ? arch->GetTriple().getTriple() : "<null>");
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getOS()) {
- case llvm::Triple::Linux:
- create = true;
- break;
-
-#if defined(__linux__)
- // Only accept "unknown" for the OS if the host is linux and it "unknown"
- // wasn't specified (it was just returned because it was NOT specified)
- case llvm::Triple::OSType::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
- default:
- break;
- }
- }
-
- LLDB_LOG(log, "create = {0}", create);
- if (create) {
- return PlatformSP(new PlatformLinux(false));
- }
- return PlatformSP();
-}
-
-ConstString PlatformLinux::GetPluginNameStatic(bool is_host) {
- if (is_host) {
- static ConstString g_host_name(Platform::GetHostPlatformName());
- return g_host_name;
- } else {
- static ConstString g_remote_name("remote-linux");
- return g_remote_name;
- }
-}
-
-const char *PlatformLinux::GetPluginDescriptionStatic(bool is_host) {
- if (is_host)
- return "Local Linux user platform plug-in.";
- else
- return "Remote Linux user platform plug-in.";
-}
-
-ConstString PlatformLinux::GetPluginName() {
- return GetPluginNameStatic(IsHost());
-}
-
-void PlatformLinux::Initialize() {
- PlatformPOSIX::Initialize();
-
- if (g_initialize_count++ == 0) {
-#if defined(__linux__) && !defined(__ANDROID__)
- PlatformSP default_platform_sp(new PlatformLinux(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform(default_platform_sp);
-#endif
- PluginManager::RegisterPlugin(
- PlatformLinux::GetPluginNameStatic(false),
- PlatformLinux::GetPluginDescriptionStatic(false),
- PlatformLinux::CreateInstance, nullptr);
- }
-}
-
-void PlatformLinux::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformLinux::CreateInstance);
- }
- }
-
- PlatformPOSIX::Terminate();
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformLinux::PlatformLinux(bool is_host)
- : PlatformPOSIX(is_host) // This is the local host platform
-{}
-
-PlatformLinux::~PlatformLinux() = default;
-
-bool PlatformLinux::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- if (IsHost()) {
- ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- if (hostArch.GetTriple().isOSLinux()) {
- if (idx == 0) {
- arch = hostArch;
- return arch.IsValid();
- } else if (idx == 1) {
- // If the default host architecture is 64-bit, look for a 32-bit
- // variant
- if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return arch.IsValid();
- }
- }
- }
- } else {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
-
- llvm::Triple triple;
- // Set the OS to linux
- triple.setOS(llvm::Triple::Linux);
- // Set the architecture
- switch (idx) {
- case 0:
- triple.setArchName("x86_64");
- break;
- case 1:
- triple.setArchName("i386");
- break;
- case 2:
- triple.setArchName("arm");
- break;
- case 3:
- triple.setArchName("aarch64");
- break;
- case 4:
- triple.setArchName("mips64");
- break;
- case 5:
- triple.setArchName("hexagon");
- break;
- case 6:
- triple.setArchName("mips");
- break;
- case 7:
- triple.setArchName("mips64el");
- break;
- case 8:
- triple.setArchName("mipsel");
- break;
- case 9:
- triple.setArchName("s390x");
- break;
- default:
- return false;
- }
- // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
- // vendor by calling triple.SetVendorName("unknown") so that it is a
- // "unspecified unknown". This means when someone calls
- // triple.GetVendorName() it will return an empty string which indicates
- // that the vendor can be set when two architectures are merged
-
- // Now set the triple into "arch" and return true
- arch.SetTriple(triple);
- return true;
- }
- return false;
-}
-
-void PlatformLinux::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
-
-#ifndef LLDB_DISABLE_POSIX
- // Display local kernel information only when we are running in host mode.
- // Otherwise, we would end up printing non-Linux information (when running on
- // Mac OS for example).
- if (IsHost()) {
- struct utsname un;
-
- if (uname(&un))
- return;
-
- strm.Printf(" Kernel: %s\n", un.sysname);
- strm.Printf(" Release: %s\n", un.release);
- strm.Printf(" Version: %s\n", un.version);
- }
-#endif
-}
-
-int32_t
-PlatformLinux::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
- int32_t resume_count = 0;
-
- // Always resume past the initial stop when we use eLaunchFlagDebug
- if (launch_info.GetFlags().Test(eLaunchFlagDebug)) {
- // Resume past the stop for the final exec into the true inferior.
- ++resume_count;
- }
-
- // If we're not launching a shell, we're done.
- const FileSpec &shell = launch_info.GetShell();
- if (!shell)
- return resume_count;
-
- std::string shell_string = shell.GetPath();
- // We're in a shell, so for sure we have to resume past the shell exec.
- ++resume_count;
-
- // Figure out what shell we're planning on using.
- const char *shell_name = strrchr(shell_string.c_str(), '/');
- if (shell_name == NULL)
- shell_name = shell_string.c_str();
- else
- shell_name++;
-
- if (strcmp(shell_name, "csh") == 0 || strcmp(shell_name, "tcsh") == 0 ||
- strcmp(shell_name, "zsh") == 0 || strcmp(shell_name, "sh") == 0) {
- // These shells seem to re-exec themselves. Add another resume.
- ++resume_count;
- }
-
- return resume_count;
-}
-
-bool PlatformLinux::CanDebugProcess() {
- if (IsHost()) {
- return true;
- } else {
- // If we're connected, we can debug.
- return IsConnected();
- }
-}
-
-// For local debugging, Linux will override the debug logic to use llgs-launch
-// rather than lldb-launch, llgs-attach. This differs from current lldb-
-// launch, debugserver-attach approach on MacOSX.
-lldb::ProcessSP
-PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new
- // target, else use existing one
- Status &error) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- LLDB_LOG(log, "target {0}", target);
-
- // If we're a remote host, use standard behavior from parent class.
- if (!IsHost())
- return PlatformPOSIX::DebugProcess(launch_info, debugger, target, error);
-
- //
- // For local debugging, we'll insist on having ProcessGDBRemote create the
- // process.
- //
-
- ProcessSP process_sp;
-
- // Make sure we stop at the entry point
- launch_info.GetFlags().Set(eLaunchFlagDebug);
-
- // We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to
- // worry about the target getting them as well.
- launch_info.SetLaunchInSeparateProcessGroup(true);
-
- // Ensure we have a target.
- if (target == nullptr) {
- LLDB_LOG(log, "creating new target");
- TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget(
- debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
- if (error.Fail()) {
- LLDB_LOG(log, "failed to create new target: {0}", error);
- return process_sp;
- }
-
- target = new_target_sp.get();
- if (!target) {
- error.SetErrorString("CreateTarget() returned nullptr");
- LLDB_LOG(log, "error: {0}", error);
- return process_sp;
- }
- }
-
- // Mark target as currently selected target.
- debugger.GetTargetList().SetSelectedTarget(target);
-
- // Now create the gdb-remote process.
- LLDB_LOG(log, "having target create process with gdb-remote plugin");
- process_sp =
- target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr);
-
- if (!process_sp) {
- error.SetErrorString("CreateProcess() failed for gdb-remote process");
- LLDB_LOG(log, "error: {0}", error);
- return process_sp;
- }
-
- LLDB_LOG(log, "successfully created process");
- // Adjust launch for a hijacker.
- ListenerSP listener_sp;
- if (!launch_info.GetHijackListener()) {
- LLDB_LOG(log, "setting up hijacker");
- listener_sp =
- Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
- launch_info.SetHijackListener(listener_sp);
- process_sp->HijackProcessEvents(listener_sp);
- }
-
- // Log file actions.
- if (log) {
- LLDB_LOG(log, "launching process with the following file actions:");
- StreamString stream;
- size_t i = 0;
- const FileAction *file_action;
- while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
- file_action->Dump(stream);
- LLDB_LOG(log, "{0}", stream.GetData());
- stream.Clear();
- }
- }
-
- // Do the launch.
- error = process_sp->Launch(launch_info);
- if (error.Success()) {
- // Handle the hijacking of process events.
- if (listener_sp) {
- const StateType state = process_sp->WaitForProcessToStop(
- llvm::None, NULL, false, listener_sp);
-
- LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
- }
-
- // Hook up process PTY if we have one (which we should for local debugging
- // with llgs).
- int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- if (pty_fd != PseudoTerminal::invalid_fd) {
- process_sp->SetSTDIOFileDescriptor(pty_fd);
- LLDB_LOG(log, "hooked up STDIO pty to process");
- } else
- LLDB_LOG(log, "not using process STDIO pty");
- } else {
- LLDB_LOG(log, "process launch failed: {0}", error);
- // FIXME figure out appropriate cleanup here. Do we delete the target? Do
- // we delete the process? Does our caller do that?
- }
-
- return process_sp;
-}
-
-void PlatformLinux::CalculateTrapHandlerSymbolNames() {
- m_trap_handlers.push_back(ConstString("_sigtramp"));
-}
-
-MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch,
- addr_t addr, addr_t length,
- unsigned prot, unsigned flags,
- addr_t fd, addr_t offset) {
- uint64_t flags_platform = 0;
- uint64_t map_anon = MAP_ANON;
-
- // To get correct flags for MIPS Architecture
- if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
- arch.GetTriple().getArch() == llvm::Triple::mips64el ||
- arch.GetTriple().getArch() == llvm::Triple::mips ||
- arch.GetTriple().getArch() == llvm::Triple::mipsel)
- map_anon = 0x800;
-
- if (flags & eMmapFlagsPrivate)
- flags_platform |= MAP_PRIVATE;
- if (flags & eMmapFlagsAnon)
- flags_platform |= map_anon;
-
- MmapArgList args({addr, length, prot, flags_platform, fd, offset});
- return args;
-}
-
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.h b/source/Plugins/Platform/Linux/PlatformLinux.h
deleted file mode 100644
index 50d721f7c0723..0000000000000
--- a/source/Plugins/Platform/Linux/PlatformLinux.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//===-- PlatformLinux.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_PlatformLinux_h_
-#define liblldb_PlatformLinux_h_
-
-#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
-
-namespace lldb_private {
-namespace platform_linux {
-
-class PlatformLinux : public PlatformPOSIX {
-public:
- PlatformLinux(bool is_host);
-
- ~PlatformLinux() override;
-
- static void Initialize();
-
- static void Terminate();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
-
- static ConstString GetPluginNameStatic(bool is_host);
-
- static const char *GetPluginDescriptionStatic(bool is_host);
-
- ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- const char *GetDescription() override {
- return GetPluginDescriptionStatic(IsHost());
- }
-
- void GetStatus(Stream &strm) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
-
- int32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override;
-
- bool CanDebugProcess() override;
-
- lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
- Debugger &debugger, Target *target,
- Status &error) override;
-
- void CalculateTrapHandlerSymbolNames() override;
-
- MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
- lldb::addr_t length, unsigned prot,
- unsigned flags, lldb::addr_t fd,
- lldb::addr_t offset) override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformLinux);
-};
-
-} // namespace platform_linux
-} // namespace lldb_private
-
-#endif // liblldb_PlatformLinux_h_
diff --git a/source/Plugins/Platform/MacOSX/CMakeLists.txt b/source/Plugins/Platform/MacOSX/CMakeLists.txt
deleted file mode 100644
index 6f0d952c35fb4..0000000000000
--- a/source/Plugins/Platform/MacOSX/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
- PlatformDarwin.cpp
- PlatformDarwinKernel.cpp
- PlatformMacOSX.cpp
- PlatformRemoteiOS.cpp
- PlatformRemoteAppleTV.cpp
- PlatformRemoteAppleWatch.cpp
- PlatformRemoteDarwinDevice.cpp
- PlatformRemoteAppleBridge.cpp
- )
-
-list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES
- PlatformAppleSimulator.cpp
- PlatformiOSSimulator.cpp
- PlatformAppleTVSimulator.cpp
- PlatformAppleWatchSimulator.cpp
- )
-
-if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
- include_directories(${LIBXML2_INCLUDE_DIR})
- add_subdirectory(objcxx)
- set(OBJC_LIBS "lldbPluginPlatformMacOSXObjCXX")
- list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
- ${PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES})
-else()
- list(APPEND LLVM_OPTIONAL_SOURCES
- ${PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES})
-endif()
-
-add_lldb_library(lldbPluginPlatformMacOSX PLUGIN
- ${PLUGIN_PLATFORM_MACOSX_SOURCES}
-
- LINK_LIBS
- clangBasic
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginPlatformPOSIX
- ${OBJC_LIBS}
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
deleted file mode 100644
index a2f74a5fc8bc9..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-//===-- PlatformAppleSimulator.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformAppleSimulator.h"
-
-#if defined(__APPLE__)
-#include <dlfcn.h>
-#endif
-
-#include <mutex>
-#include <thread>
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-#include "llvm/Support/Threading.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#if !defined(__APPLE__)
-#define UNSUPPORTED_ERROR ("Apple simulators aren't supported on this platform")
-#endif
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformAppleSimulator::Initialize() { PlatformDarwin::Initialize(); }
-
-void PlatformAppleSimulator::Terminate() { PlatformDarwin::Terminate(); }
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformAppleSimulator::PlatformAppleSimulator()
- : PlatformDarwin(true), m_core_sim_path_mutex(),
- m_core_simulator_framework_path(), m_device() {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformAppleSimulator::~PlatformAppleSimulator() {}
-
-lldb_private::Status PlatformAppleSimulator::LaunchProcess(
- lldb_private::ProcessLaunchInfo &launch_info) {
-#if defined(__APPLE__)
- LoadCoreSimulator();
- CoreSimulatorSupport::Device device(GetSimulatorDevice());
-
- if (device.GetState() != CoreSimulatorSupport::Device::State::Booted) {
- Status boot_err;
- device.Boot(boot_err);
- if (boot_err.Fail())
- return boot_err;
- }
-
- auto spawned = device.Spawn(launch_info);
-
- if (spawned) {
- launch_info.SetProcessID(spawned.GetPID());
- return Status();
- } else
- return spawned.GetError();
-#else
- Status err;
- err.SetErrorString(UNSUPPORTED_ERROR);
- return err;
-#endif
-}
-
-void PlatformAppleSimulator::GetStatus(Stream &strm) {
-#if defined(__APPLE__)
- // This will get called by subclasses, so just output status on the current
- // simulator
- PlatformAppleSimulator::LoadCoreSimulator();
-
- CoreSimulatorSupport::DeviceSet devices =
- CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
- GetDeveloperDirectory());
- const size_t num_devices = devices.GetNumDevices();
- if (num_devices) {
- strm.Printf("Available devices:\n");
- for (size_t i = 0; i < num_devices; ++i) {
- CoreSimulatorSupport::Device device = devices.GetDeviceAtIndex(i);
- strm.Printf(" %s: %s\n", device.GetUDID().c_str(),
- device.GetName().c_str());
- }
-
- if (m_device.hasValue() && m_device->operator bool()) {
- strm.Printf("Current device: %s: %s", m_device->GetUDID().c_str(),
- m_device->GetName().c_str());
- if (m_device->GetState() == CoreSimulatorSupport::Device::State::Booted) {
- strm.Printf(" state = booted");
- }
- strm.Printf("\nType \"platform connect <ARG>\" where <ARG> is a device "
- "UDID or a device name to disconnect and connect to a "
- "different device.\n");
-
- } else {
- strm.Printf("No current device is selected, \"platform connect <ARG>\" "
- "where <ARG> is a device UDID or a device name to connect to "
- "a specific device.\n");
- }
-
- } else {
- strm.Printf("No devices are available.\n");
- }
-#else
- strm.Printf(UNSUPPORTED_ERROR);
-#endif
-}
-
-Status PlatformAppleSimulator::ConnectRemote(Args &args) {
-#if defined(__APPLE__)
- Status error;
- if (args.GetArgumentCount() == 1) {
- if (m_device)
- DisconnectRemote();
- PlatformAppleSimulator::LoadCoreSimulator();
- const char *arg_cstr = args.GetArgumentAtIndex(0);
- if (arg_cstr) {
- std::string arg_str(arg_cstr);
- CoreSimulatorSupport::DeviceSet devices =
- CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
- GetDeveloperDirectory());
- devices.ForEach(
- [this, &arg_str](const CoreSimulatorSupport::Device &device) -> bool {
- if (arg_str == device.GetUDID() || arg_str == device.GetName()) {
- m_device = device;
- return false; // Stop iterating
- } else {
- return true; // Keep iterating
- }
- });
- if (!m_device)
- error.SetErrorStringWithFormat(
- "no device with UDID or name '%s' was found", arg_cstr);
- }
- } else {
- error.SetErrorString("this command take a single UDID argument of the "
- "device you want to connect to.");
- }
- return error;
-#else
- Status err;
- err.SetErrorString(UNSUPPORTED_ERROR);
- return err;
-#endif
-}
-
-Status PlatformAppleSimulator::DisconnectRemote() {
-#if defined(__APPLE__)
- m_device.reset();
- return Status();
-#else
- Status err;
- err.SetErrorString(UNSUPPORTED_ERROR);
- return err;
-#endif
-}
-
-lldb::ProcessSP PlatformAppleSimulator::DebugProcess(
- ProcessLaunchInfo &launch_info, Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use
- // existing one
- Status &error) {
-#if defined(__APPLE__)
- ProcessSP process_sp;
- // Make sure we stop at the entry point
- launch_info.GetFlags().Set(eLaunchFlagDebug);
- // We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to
- // worry about the target getting them as well.
- launch_info.SetLaunchInSeparateProcessGroup(true);
-
- error = LaunchProcess(launch_info);
- if (error.Success()) {
- if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
- ProcessAttachInfo attach_info(launch_info);
- process_sp = Attach(attach_info, debugger, target, error);
- if (process_sp) {
- launch_info.SetHijackListener(attach_info.GetHijackListener());
-
- // Since we attached to the process, it will think it needs to detach
- // if the process object just goes away without an explicit call to
- // Process::Kill() or Process::Detach(), so let it know to kill the
- // process if this happens.
- process_sp->SetShouldDetach(false);
-
- // If we didn't have any file actions, the pseudo terminal might have
- // been used where the slave side was given as the file to open for
- // stdin/out/err after we have already opened the master so we can
- // read/write stdin/out/err.
- int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- if (pty_fd != PseudoTerminal::invalid_fd) {
- process_sp->SetSTDIOFileDescriptor(pty_fd);
- }
- }
- }
- }
-
- return process_sp;
-#else
- return ProcessSP();
-#endif
-}
-
-FileSpec PlatformAppleSimulator::GetCoreSimulatorPath() {
-#if defined(__APPLE__)
- std::lock_guard<std::mutex> guard(m_core_sim_path_mutex);
- if (!m_core_simulator_framework_path.hasValue()) {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir) {
- StreamString cs_path;
- cs_path.Printf(
- "%s/Library/PrivateFrameworks/CoreSimulator.framework/CoreSimulator",
- developer_dir);
- m_core_simulator_framework_path = FileSpec(cs_path.GetData());
- FileSystem::Instance().Resolve(*m_core_simulator_framework_path);
- }
- }
-
- return m_core_simulator_framework_path.getValue();
-#else
- return FileSpec();
-#endif
-}
-
-void PlatformAppleSimulator::LoadCoreSimulator() {
-#if defined(__APPLE__)
- static llvm::once_flag g_load_core_sim_flag;
- llvm::call_once(g_load_core_sim_flag, [this] {
- const std::string core_sim_path(GetCoreSimulatorPath().GetPath());
- if (core_sim_path.size())
- dlopen(core_sim_path.c_str(), RTLD_LAZY);
- });
-#endif
-}
-
-#if defined(__APPLE__)
-CoreSimulatorSupport::Device PlatformAppleSimulator::GetSimulatorDevice() {
- if (!m_device.hasValue()) {
- const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id =
- CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone;
- m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
- GetDeveloperDirectory())
- .GetFanciest(dev_id);
- }
-
- if (m_device.hasValue())
- return m_device.getValue();
- else
- return CoreSimulatorSupport::Device();
-}
-#endif
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
deleted file mode 100644
index daae376cc00b5..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- PlatformAppleSimulator.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_PlatformAppleSimulator_h_
-#define liblldb_PlatformAppleSimulator_h_
-
-#include <mutex>
-
-#include "Plugins/Platform/MacOSX/PlatformDarwin.h"
-#include "Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h"
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/ADT/Optional.h"
-
-class PlatformAppleSimulator : public PlatformDarwin {
-public:
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformAppleSimulator();
-
- virtual ~PlatformAppleSimulator();
-
- lldb_private::Status
- LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- lldb_private::Status ConnectRemote(lldb_private::Args &args) override;
-
- lldb_private::Status DisconnectRemote() override;
-
- lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Status &error) override;
-
-protected:
- std::mutex m_core_sim_path_mutex;
- llvm::Optional<lldb_private::FileSpec> m_core_simulator_framework_path;
- llvm::Optional<CoreSimulatorSupport::Device> m_device;
-
- lldb_private::FileSpec GetCoreSimulatorPath();
-
- void LoadCoreSimulator();
-
-#if defined(__APPLE__)
- CoreSimulatorSupport::Device GetSimulatorDevice();
-#endif
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformAppleSimulator);
-};
-
-#endif // liblldb_PlatformAppleSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
deleted file mode 100644
index 62bd3c3ed1f81..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-//===-- PlatformAppleTVSimulator.cpp ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformAppleTVSimulator.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "llvm/Support/FileSystem.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformAppleTVSimulator::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(
- PlatformAppleTVSimulator::GetPluginNameStatic(),
- PlatformAppleTVSimulator::GetDescriptionStatic(),
- PlatformAppleTVSimulator::CreateInstance);
- }
-}
-
-void PlatformAppleTVSimulator::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformAppleTVSimulator::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformAppleTVSimulator::CreateInstance(bool force,
- const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformAppleTVSimulator::%s(force=%s, arch={%s,%s})",
- __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::x86_64: {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and it
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-#endif
- default:
- break;
- }
-
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::TvOS:
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and it
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
- default:
- create = false;
- break;
- }
- }
- } break;
- default:
- break;
- }
- }
- if (create) {
- if (log)
- log->Printf("PlatformAppleTVSimulator::%s() creating platform",
- __FUNCTION__);
-
- return PlatformSP(new PlatformAppleTVSimulator());
- }
-
- if (log)
- log->Printf("PlatformAppleTVSimulator::%s() aborting creation of platform",
- __FUNCTION__);
-
- return PlatformSP();
-}
-
-lldb_private::ConstString PlatformAppleTVSimulator::GetPluginNameStatic() {
- static ConstString g_name("tvos-simulator");
- return g_name;
-}
-
-const char *PlatformAppleTVSimulator::GetDescriptionStatic() {
- return "Apple TV simulator platform plug-in.";
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformAppleTVSimulator::PlatformAppleTVSimulator()
- : PlatformDarwin(true), m_sdk_dir_mutex(), m_sdk_directory() {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformAppleTVSimulator::~PlatformAppleTVSimulator() {}
-
-void PlatformAppleTVSimulator::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- const char *sdk_directory = GetSDKDirectoryAsCString();
- if (sdk_directory)
- strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString(" SDK Path: error: unable to locate SDK\n");
-}
-
-Status PlatformAppleTVSimulator::ResolveExecutable(
- const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Status error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(module_spec);
-
- // If we have "ls" as the exe_file, resolve the executable loation based on
- // the current path variables
- // TODO: resolve bare executables in the Platform SDK
- // if (!resolved_exe_file.Exists())
- // resolved_exe_file.ResolveExecutableLocation ();
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one
- // ourselves
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
- if (resolved_module_spec.GetArchitecture().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't found
- // so ask the platform for the architectures that we should be using (in
- // the correct order) and see if we can find a match that way
- StreamString arch_names;
- ArchSpec platform_arch;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- // Only match x86 with x86 and x86_64 with x86_64...
- if (!module_spec.GetArchitecture().IsValid() ||
- module_spec.GetArchitecture().GetCore() ==
- resolved_module_spec.GetArchitecture().GetCore()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(platform_arch.GetArchitectureName());
- }
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetString().str().c_str());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- } else {
- error.SetErrorStringWithFormat("'%s' does not exist",
- module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-static FileSystem::EnumerateDirectoryResult
-EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft,
- llvm::StringRef path) {
- if (ft == llvm::sys::fs::file_type::directory_file) {
- FileSpec file_spec(path);
- const char *filename = file_spec.GetFilename().GetCString();
- if (filename &&
- strncmp(filename, "AppleTVSimulator", strlen("AppleTVSimulator")) ==
- 0) {
- ::snprintf((char *)baton, PATH_MAX, "%s", filename);
- return FileSystem::eEnumerateDirectoryResultQuit;
- }
- }
- return FileSystem::eEnumerateDirectoryResultNext;
-}
-
-const char *PlatformAppleTVSimulator::GetSDKDirectoryAsCString() {
- std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
- if (m_sdk_directory.empty()) {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir) {
- char sdks_directory[PATH_MAX];
- char sdk_dirname[PATH_MAX];
- sdk_dirname[0] = '\0';
- snprintf(sdks_directory, sizeof(sdks_directory),
- "%s/Platforms/AppleTVSimulator.platform/Developer/SDKs",
- developer_dir);
- FileSpec simulator_sdk_spec;
- bool find_directories = true;
- bool find_files = false;
- bool find_other = false;
- FileSystem::Instance().EnumerateDirectory(
- sdks_directory, find_directories, find_files, find_other,
- EnumerateDirectoryCallback, sdk_dirname);
-
- if (sdk_dirname[0]) {
- m_sdk_directory = sdks_directory;
- m_sdk_directory.append(1, '/');
- m_sdk_directory.append(sdk_dirname);
- return m_sdk_directory.c_str();
- }
- }
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_sdk_directory.assign(1, '\0');
- }
-
- // We should have put a single NULL character into m_sdk_directory or it
- // should have a valid path if the code gets here
- assert(m_sdk_directory.empty() == false);
- if (m_sdk_directory[0])
- return m_sdk_directory.c_str();
- return NULL;
-}
-
-Status PlatformAppleTVSimulator::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- Status error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- char resolved_path[PATH_MAX];
-
- const char *sdk_dir = GetSDKDirectoryAsCString();
- if (sdk_dir) {
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
- platform_file_path);
-
- // First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file))
- return error;
-
- // Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file))
- return error;
- }
- error.SetErrorStringWithFormat(
- "unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path, GetPluginName().GetCString());
- } else {
- error.SetErrorString("invalid platform file argument");
- }
- return error;
-}
-
-Status PlatformAppleTVSimulator::GetSharedModule(
- const ModuleSpec &module_spec, lldb_private::Process *process,
- ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
- // For AppleTV, the SDK files are all cached locally on the host system. So
- // first we ask for the file in the cached SDK, then we attempt to get a
- // shared module for the right architecture with the right UUID.
- Status error;
- ModuleSpec platform_module_spec(module_spec);
- const FileSpec &platform_file = module_spec.GetFileSpec();
- error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
- platform_module_spec.GetFileSpec());
- if (error.Success()) {
- error = ResolveExecutable(platform_module_spec, module_sp,
- module_search_paths_ptr);
- } else {
- const bool always_create = false;
- error = ModuleList::GetSharedModule(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr, always_create);
- }
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
-}
-
-uint32_t PlatformAppleTVSimulator::FindProcesses(
- const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) {
- ProcessInstanceInfoList all_osx_process_infos;
- // First we get all OSX processes
- const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
-
- // Now we filter them down to only the TvOS triples
- for (uint32_t i = 0; i < n; ++i) {
- const ProcessInstanceInfo &proc_info =
- all_osx_process_infos.GetProcessInfoAtIndex(i);
- if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::TvOS) {
- process_infos.Append(proc_info);
- }
- }
- return process_infos.GetSize();
-}
-
-bool PlatformAppleTVSimulator::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- static const ArchSpec platform_arch(
- HostInfo::GetArchitecture(HostInfo::eArchKind64));
-
- if (idx == 0) {
- arch = platform_arch;
- if (arch.IsValid()) {
- arch.GetTriple().setOS(llvm::Triple::TvOS);
- return true;
- }
- }
- return false;
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
deleted file mode 100644
index 9a4da589c7ead..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- PlatformAppleTVSimulator.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_PlatformAppleTVSimulator_h_
-#define liblldb_PlatformAppleTVSimulator_h_
-
-#include "PlatformDarwin.h"
-
-class PlatformAppleTVSimulator : public PlatformDarwin {
-public:
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformAppleTVSimulator();
-
- virtual ~PlatformAppleTVSimulator();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Status ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- virtual lldb_private::Status
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- uint32_t
- FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::iPhoneSimulator);
- }
-
-protected:
- std::mutex m_sdk_dir_mutex;
- std::string m_sdk_directory;
- std::string m_build_update;
-
- const char *GetSDKDirectoryAsCString();
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformAppleTVSimulator);
-};
-
-#endif // liblldb_PlatformAppleTVSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
deleted file mode 100644
index ec112cc0b9c52..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
+++ /dev/null
@@ -1,394 +0,0 @@
-//===-- PlatformAppleWatchSimulator.cpp -------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformAppleWatchSimulator.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformAppleWatchSimulator::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(
- PlatformAppleWatchSimulator::GetPluginNameStatic(),
- PlatformAppleWatchSimulator::GetDescriptionStatic(),
- PlatformAppleWatchSimulator::CreateInstance);
- }
-}
-
-void PlatformAppleWatchSimulator::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(
- PlatformAppleWatchSimulator::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformAppleWatchSimulator::CreateInstance(bool force,
- const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformAppleWatchSimulator::%s(force=%s, arch={%s,%s})",
- __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::x86_64: {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and it
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-#endif
- default:
- break;
- }
-
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::WatchOS:
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and it
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
- default:
- create = false;
- break;
- }
- }
- } break;
- default:
- break;
- }
- }
- if (create) {
- if (log)
- log->Printf("PlatformAppleWatchSimulator::%s() creating platform",
- __FUNCTION__);
-
- return PlatformSP(new PlatformAppleWatchSimulator());
- }
-
- if (log)
- log->Printf(
- "PlatformAppleWatchSimulator::%s() aborting creation of platform",
- __FUNCTION__);
-
- return PlatformSP();
-}
-
-lldb_private::ConstString PlatformAppleWatchSimulator::GetPluginNameStatic() {
- static ConstString g_name("watchos-simulator");
- return g_name;
-}
-
-const char *PlatformAppleWatchSimulator::GetDescriptionStatic() {
- return "Apple Watch simulator platform plug-in.";
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformAppleWatchSimulator::PlatformAppleWatchSimulator()
- : PlatformDarwin(true), m_sdk_directory() {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformAppleWatchSimulator::~PlatformAppleWatchSimulator() {}
-
-void PlatformAppleWatchSimulator::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- const char *sdk_directory = GetSDKDirectoryAsCString();
- if (sdk_directory)
- strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString(" SDK Path: error: unable to locate SDK\n");
-}
-
-Status PlatformAppleWatchSimulator::ResolveExecutable(
- const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Status error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(module_spec);
-
- // If we have "ls" as the exe_file, resolve the executable loation based on
- // the current path variables
- // TODO: resolve bare executables in the Platform SDK
- // if (!resolved_exe_file.Exists())
- // resolved_exe_file.ResolveExecutableLocation ();
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one
- // ourselves
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
- if (resolved_module_spec.GetArchitecture().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't found
- // so ask the platform for the architectures that we should be using (in
- // the correct order) and see if we can find a match that way
- StreamString arch_names;
- ArchSpec platform_arch;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- // Only match x86 with x86 and x86_64 with x86_64...
- if (!module_spec.GetArchitecture().IsValid() ||
- module_spec.GetArchitecture().GetCore() ==
- resolved_module_spec.GetArchitecture().GetCore()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(platform_arch.GetArchitectureName());
- }
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetString().str().c_str());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- } else {
- error.SetErrorStringWithFormat("'%s' does not exist",
- module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-static FileSystem::EnumerateDirectoryResult
-EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft,
- llvm::StringRef path) {
- if (ft == llvm::sys::fs::file_type::directory_file) {
- FileSpec file_spec(path);
- const char *filename = file_spec.GetFilename().GetCString();
- if (filename &&
- strncmp(filename, "AppleWatchSimulator",
- strlen("AppleWatchSimulator")) == 0) {
- ::snprintf((char *)baton, PATH_MAX, "%s", filename);
- return FileSystem::eEnumerateDirectoryResultQuit;
- }
- }
- return FileSystem::eEnumerateDirectoryResultNext;
-}
-
-const char *PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() {
- std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
- if (m_sdk_directory.empty()) {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir) {
- char sdks_directory[PATH_MAX];
- char sdk_dirname[PATH_MAX];
- sdk_dirname[0] = '\0';
- snprintf(sdks_directory, sizeof(sdks_directory),
- "%s/Platforms/AppleWatchSimulator.platform/Developer/SDKs",
- developer_dir);
- FileSpec simulator_sdk_spec;
- bool find_directories = true;
- bool find_files = false;
- bool find_other = false;
- FileSystem::Instance().EnumerateDirectory(
- sdks_directory, find_directories, find_files, find_other,
- EnumerateDirectoryCallback, sdk_dirname);
-
- if (sdk_dirname[0]) {
- m_sdk_directory = sdks_directory;
- m_sdk_directory.append(1, '/');
- m_sdk_directory.append(sdk_dirname);
- return m_sdk_directory.c_str();
- }
- }
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_sdk_directory.assign(1, '\0');
- }
-
- // We should have put a single NULL character into m_sdk_directory or it
- // should have a valid path if the code gets here
- assert(m_sdk_directory.empty() == false);
- if (m_sdk_directory[0])
- return m_sdk_directory.c_str();
- return NULL;
-}
-
-Status PlatformAppleWatchSimulator::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- Status error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- char resolved_path[PATH_MAX];
-
- const char *sdk_dir = GetSDKDirectoryAsCString();
- if (sdk_dir) {
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
- platform_file_path);
-
- // First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file))
- return error;
-
- // Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file))
- return error;
- }
- error.SetErrorStringWithFormat(
- "unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path, GetPluginName().GetCString());
- } else {
- error.SetErrorString("invalid platform file argument");
- }
- return error;
-}
-
-Status PlatformAppleWatchSimulator::GetSharedModule(
- const ModuleSpec &module_spec, lldb_private::Process *process,
- ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
- // For AppleWatch, the SDK files are all cached locally on the host system.
- // So first we ask for the file in the cached SDK, then we attempt to get a
- // shared module for the right architecture with the right UUID.
- Status error;
- ModuleSpec platform_module_spec(module_spec);
- const FileSpec &platform_file = module_spec.GetFileSpec();
- error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
- platform_module_spec.GetFileSpec());
- if (error.Success()) {
- error = ResolveExecutable(platform_module_spec, module_sp,
- module_search_paths_ptr);
- } else {
- const bool always_create = false;
- error = ModuleList::GetSharedModule(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr, always_create);
- }
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
-}
-
-uint32_t PlatformAppleWatchSimulator::FindProcesses(
- const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) {
- ProcessInstanceInfoList all_osx_process_infos;
- // First we get all OSX processes
- const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
-
- // Now we filter them down to only the WatchOS triples
- for (uint32_t i = 0; i < n; ++i) {
- const ProcessInstanceInfo &proc_info =
- all_osx_process_infos.GetProcessInfoAtIndex(i);
- if (proc_info.GetArchitecture().GetTriple().getOS() ==
- llvm::Triple::WatchOS) {
- process_infos.Append(proc_info);
- }
- }
- return process_infos.GetSize();
-}
-
-bool PlatformAppleWatchSimulator::GetSupportedArchitectureAtIndex(
- uint32_t idx, ArchSpec &arch) {
- static const ArchSpec platform_arch(
- HostInfo::GetArchitecture(HostInfo::eArchKind64));
-
- if (idx == 0) {
- arch = platform_arch;
- if (arch.IsValid()) {
- arch.GetTriple().setOS(llvm::Triple::WatchOS);
- return true;
- }
- }
- return false;
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
deleted file mode 100644
index c240a09e3afd1..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- PlatformAppleWatchSimulator.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_PlatformAppleWatchSimulator_h_
-#define liblldb_PlatformAppleWatchSimulator_h_
-
-#include "PlatformDarwin.h"
-
-class PlatformAppleWatchSimulator : public PlatformDarwin {
-public:
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformAppleWatchSimulator();
-
- virtual ~PlatformAppleWatchSimulator();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Status ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- virtual lldb_private::Status
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- uint32_t
- FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::iPhoneSimulator);
- }
-
-protected:
- std::mutex m_sdk_dir_mutex;
- std::string m_sdk_directory;
- std::string m_build_update;
-
- const char *GetSDKDirectoryAsCString();
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformAppleWatchSimulator);
-};
-
-#endif // liblldb_PlatformAppleWatchSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
deleted file mode 100644
index 3868d97700e07..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ /dev/null
@@ -1,1757 +0,0 @@
-//===-- PlatformDarwin.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformDarwin.h"
-
-#include <string.h>
-
-#include <algorithm>
-#include <mutex>
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/BreakpointSite.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/Symbols.h"
-#include "lldb/Host/XML.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Timer.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Threading.h"
-#include "llvm/Support/VersionTuple.h"
-
-#if defined(__APPLE__)
-#include <TargetConditionals.h>
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformDarwin::PlatformDarwin(bool is_host)
- : PlatformPOSIX(is_host), // This is the local host platform
- m_developer_directory() {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformDarwin::~PlatformDarwin() {}
-
-FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
- Target *target, Module &module, Stream *feedback_stream) {
- FileSpecList file_list;
- if (target &&
- target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython) {
- // NB some extensions might be meaningful and should not be stripped -
- // "this.binary.file"
- // should not lose ".file" but GetFileNameStrippingExtension() will do
- // precisely that. Ideally, we should have a per-platform list of
- // extensions (".exe", ".app", ".dSYM", ".framework") which should be
- // stripped while leaving "this.binary.file" as-is.
- ScriptInterpreter *script_interpreter =
- target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
-
- FileSpec module_spec = module.GetFileSpec();
-
- if (module_spec) {
- SymbolVendor *symbols = module.GetSymbolVendor();
- if (symbols) {
- SymbolFile *symfile = symbols->GetSymbolFile();
- if (symfile) {
- ObjectFile *objfile = symfile->GetObjectFile();
- if (objfile) {
- FileSpec symfile_spec(objfile->GetFileSpec());
- if (symfile_spec && FileSystem::Instance().Exists(symfile_spec)) {
- while (module_spec.GetFilename()) {
- std::string module_basename(
- module_spec.GetFilename().GetCString());
- std::string original_module_basename(module_basename);
-
- bool was_keyword = false;
-
- // FIXME: for Python, we cannot allow certain characters in
- // module
- // filenames we import. Theoretically, different scripting
- // languages may have different sets of forbidden tokens in
- // filenames, and that should be dealt with by each
- // ScriptInterpreter. For now, we just replace dots with
- // underscores, but if we ever support anything other than
- // Python we will need to rework this
- std::replace(module_basename.begin(), module_basename.end(),
- '.', '_');
- std::replace(module_basename.begin(), module_basename.end(),
- ' ', '_');
- std::replace(module_basename.begin(), module_basename.end(),
- '-', '_');
- if (script_interpreter &&
- script_interpreter->IsReservedWord(
- module_basename.c_str())) {
- module_basename.insert(module_basename.begin(), '_');
- was_keyword = true;
- }
-
- StreamString path_string;
- StreamString original_path_string;
- // for OSX we are going to be in
- // .dSYM/Contents/Resources/DWARF/<basename> let us go to
- // .dSYM/Contents/Resources/Python/<basename>.py and see if the
- // file exists
- path_string.Printf("%s/../Python/%s.py",
- symfile_spec.GetDirectory().GetCString(),
- module_basename.c_str());
- original_path_string.Printf(
- "%s/../Python/%s.py",
- symfile_spec.GetDirectory().GetCString(),
- original_module_basename.c_str());
- FileSpec script_fspec(path_string.GetString());
- FileSystem::Instance().Resolve(script_fspec);
- FileSpec orig_script_fspec(original_path_string.GetString());
- FileSystem::Instance().Resolve(orig_script_fspec);
-
- // if we did some replacements of reserved characters, and a
- // file with the untampered name exists, then warn the user
- // that the file as-is shall not be loaded
- if (feedback_stream) {
- if (module_basename != original_module_basename &&
- FileSystem::Instance().Exists(orig_script_fspec)) {
- const char *reason_for_complaint =
- was_keyword ? "conflicts with a keyword"
- : "contains reserved characters";
- if (FileSystem::Instance().Exists(script_fspec))
- feedback_stream->Printf(
- "warning: the symbol file '%s' contains a debug "
- "script. However, its name"
- " '%s' %s and as such cannot be loaded. LLDB will"
- " load '%s' instead. Consider removing the file with "
- "the malformed name to"
- " eliminate this warning.\n",
- symfile_spec.GetPath().c_str(),
- original_path_string.GetData(), reason_for_complaint,
- path_string.GetData());
- else
- feedback_stream->Printf(
- "warning: the symbol file '%s' contains a debug "
- "script. However, its name"
- " %s and as such cannot be loaded. If you intend"
- " to have this script loaded, please rename '%s' to "
- "'%s' and retry.\n",
- symfile_spec.GetPath().c_str(), reason_for_complaint,
- original_path_string.GetData(),
- path_string.GetData());
- }
- }
-
- if (FileSystem::Instance().Exists(script_fspec)) {
- file_list.Append(script_fspec);
- break;
- }
-
- // If we didn't find the python file, then keep stripping the
- // extensions and try again
- ConstString filename_no_extension(
- module_spec.GetFileNameStrippingExtension());
- if (module_spec.GetFilename() == filename_no_extension)
- break;
-
- module_spec.GetFilename() = filename_no_extension;
- }
- }
- }
- }
- }
- }
- }
- return file_list;
-}
-
-Status PlatformDarwin::ResolveSymbolFile(Target &target,
- const ModuleSpec &sym_spec,
- FileSpec &sym_file) {
- sym_file = sym_spec.GetSymbolFileSpec();
- if (FileSystem::Instance().IsDirectory(sym_file)) {
- sym_file = Symbols::FindSymbolFileInBundle(sym_file, sym_spec.GetUUIDPtr(),
- sym_spec.GetArchitecturePtr());
- }
- return {};
-}
-
-static lldb_private::Status
-MakeCacheFolderForFile(const FileSpec &module_cache_spec) {
- FileSpec module_cache_folder =
- module_cache_spec.CopyByRemovingLastPathComponent();
- return llvm::sys::fs::create_directory(module_cache_folder.GetPath());
-}
-
-static lldb_private::Status
-BringInRemoteFile(Platform *platform,
- const lldb_private::ModuleSpec &module_spec,
- const FileSpec &module_cache_spec) {
- MakeCacheFolderForFile(module_cache_spec);
- Status err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
- return err;
-}
-
-lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol "
- "path %s/%s",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString(),
- module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
- module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
- module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
- module_spec.GetSymbolFileSpec().GetFilename().AsCString());
-
- Status err;
-
- err = ModuleList::GetSharedModule(module_spec, module_sp,
- module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr);
- if (module_sp)
- return err;
-
- if (!IsHost()) {
- std::string cache_path(GetLocalCacheDirectory());
- // Only search for a locally cached file if we have a valid cache path
- if (!cache_path.empty()) {
- std::string module_path(module_spec.GetFileSpec().GetPath());
- cache_path.append(module_path);
- FileSpec module_cache_spec(cache_path);
-
- // if rsync is supported, always bring in the file - rsync will be very
- // efficient when files are the same on the local and remote end of the
- // connection
- if (this->GetSupportsRSync()) {
- err = BringInRemoteFile(this, module_spec, module_cache_spec);
- if (err.Fail())
- return err;
- if (FileSystem::Instance().Exists(module_cache_spec)) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] module %s/%s was rsynced and is now there",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- ModuleSpec local_spec(module_cache_spec,
- module_spec.GetArchitecture());
- module_sp.reset(new Module(local_spec));
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return Status();
- }
- }
-
- // try to find the module in the cache
- if (FileSystem::Instance().Exists(module_cache_spec)) {
- // get the local and remote MD5 and compare
- if (m_remote_platform_sp) {
- // when going over the *slow* GDB remote transfer mechanism we first
- // check the hashes of the files - and only do the actual transfer if
- // they differ
- uint64_t high_local, high_remote, low_local, low_remote;
- auto MD5 = llvm::sys::fs::md5_contents(module_cache_spec.GetPath());
- if (!MD5)
- return Status(MD5.getError());
- std::tie(high_local, low_local) = MD5->words();
-
- m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(),
- low_remote, high_remote);
- if (low_local != low_remote || high_local != high_remote) {
- // bring in the remote file
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf(
- "[%s] module %s/%s needs to be replaced from remote copy",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- Status err =
- BringInRemoteFile(this, module_spec, module_cache_spec);
- if (err.Fail())
- return err;
- }
- }
-
- ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
- module_sp.reset(new Module(local_spec));
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] module %s/%s was found in the cache",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- return Status();
- }
-
- // bring in the remote module file
- if (log)
- log->Printf("[%s] module %s/%s needs to come in remotely",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- Status err = BringInRemoteFile(this, module_spec, module_cache_spec);
- if (err.Fail())
- return err;
- if (FileSystem::Instance().Exists(module_cache_spec)) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] module %s/%s is now cached and fine",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
- module_sp.reset(new Module(local_spec));
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return Status();
- } else
- return Status("unable to obtain valid module file");
- } else
- return Status("no cache path");
- } else
- return Status("unable to resolve module");
-}
-
-Status PlatformDarwin::GetSharedModule(
- const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) {
- Status error;
- module_sp.reset();
-
- if (IsRemote()) {
- // If we have a remote platform always, let it try and locate the shared
- // module first.
- if (m_remote_platform_sp) {
- error = m_remote_platform_sp->GetSharedModule(
- module_spec, process, module_sp, module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- }
- }
-
- if (!module_sp) {
- // Fall back to the local platform and find the file locally
- error = Platform::GetSharedModule(module_spec, process, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
-
- const FileSpec &platform_file = module_spec.GetFileSpec();
- if (!module_sp && module_search_paths_ptr && platform_file) {
- // We can try to pull off part of the file path up to the bundle
- // directory level and try any module search paths...
- FileSpec bundle_directory;
- if (Host::GetBundleDirectory(platform_file, bundle_directory)) {
- if (platform_file == bundle_directory) {
- ModuleSpec new_module_spec(module_spec);
- new_module_spec.GetFileSpec() = bundle_directory;
- if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) {
- Status new_error(Platform::GetSharedModule(
- new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
- return new_error;
- }
- } else {
- char platform_path[PATH_MAX];
- char bundle_dir[PATH_MAX];
- platform_file.GetPath(platform_path, sizeof(platform_path));
- const size_t bundle_directory_len =
- bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir));
- char new_path[PATH_MAX];
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i) {
- const size_t search_path_len =
- module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(
- new_path, sizeof(new_path));
- if (search_path_len < sizeof(new_path)) {
- snprintf(new_path + search_path_len,
- sizeof(new_path) - search_path_len, "/%s",
- platform_path + bundle_directory_len);
- FileSpec new_file_spec(new_path);
- if (FileSystem::Instance().Exists(new_file_spec)) {
- ModuleSpec new_module_spec(module_spec);
- new_module_spec.GetFileSpec() = new_file_spec;
- Status new_error(Platform::GetSharedModule(
- new_module_spec, process, module_sp, NULL,
- old_module_sp_ptr, did_create_ptr));
-
- if (module_sp) {
- module_sp->SetPlatformFileSpec(new_file_spec);
- return new_error;
- }
- }
- }
- }
- }
- }
- }
- }
- if (module_sp)
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return error;
-}
-
-size_t
-PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,
- BreakpointSite *bp_site) {
- const uint8_t *trap_opcode = nullptr;
- uint32_t trap_opcode_size = 0;
- bool bp_is_thumb = false;
-
- llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
- switch (machine) {
- case llvm::Triple::aarch64: {
- // TODO: fix this with actual darwin breakpoint opcode for arm64.
- // right now debugging uses the Z packets with GDB remote so this is not
- // needed, but the size needs to be correct...
- static const uint8_t g_arm64_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
- trap_opcode = g_arm64_breakpoint_opcode;
- trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
- } break;
-
- case llvm::Triple::thumb:
- bp_is_thumb = true;
- LLVM_FALLTHROUGH;
- case llvm::Triple::arm: {
- static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
- static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE};
-
- // Auto detect arm/thumb if it wasn't explicitly specified
- if (!bp_is_thumb) {
- lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
- if (bp_loc_sp)
- bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
- AddressClass::eCodeAlternateISA;
- }
- if (bp_is_thumb) {
- trap_opcode = g_thumb_breakpooint_opcode;
- trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
- break;
- }
- trap_opcode = g_arm_breakpoint_opcode;
- trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
- } break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64: {
- static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
- trap_opcode = g_ppc_breakpoint_opcode;
- trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
- } break;
-
- default:
- return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
- }
-
- if (trap_opcode && trap_opcode_size) {
- if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
- return trap_opcode_size;
- }
- return 0;
-}
-
-bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches(
- lldb_private::Target &target, const lldb::ModuleSP &module_sp) {
- if (!module_sp)
- return false;
-
- ObjectFile *obj_file = module_sp->GetObjectFile();
- if (!obj_file)
- return false;
-
- ObjectFile::Type obj_type = obj_file->GetType();
- return obj_type == ObjectFile::eTypeDynamicLinker;
-}
-
-bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) {
- switch (idx) {
- case 0:
- arch = host_arch;
- return true;
-
- case 1:
- arch.SetTriple("x86_64-apple-macosx");
- return true;
-
- case 2:
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return true;
-
- default:
- return false;
- }
- } else {
- if (idx == 0) {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- return arch.IsValid();
- } else if (idx == 1) {
- ArchSpec platform_arch(
- HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
- ArchSpec platform_arch64(
- HostInfo::GetArchitecture(HostInfo::eArchKind64));
- if (platform_arch.IsExactMatch(platform_arch64)) {
- // This macosx platform supports both 32 and 64 bit. Since we already
- // returned the 64 bit arch for idx == 0, return the 32 bit arch for
- // idx == 1
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return arch.IsValid();
- }
- }
- }
- return false;
-}
-
-// The architecture selection rules for arm processors These cpu subtypes have
-// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f
-// processor.
-
-bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- ArchSpec system_arch(GetSystemArchitecture());
-
-// When lldb is running on a watch or tv, set the arch OS name appropriately.
-#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
-#define OSNAME "tvos"
-#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
-#define OSNAME "watchos"
-#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
-#define OSNAME "bridgeos"
-#else
-#define OSNAME "ios"
-#endif
-
- const ArchSpec::Core system_core = system_arch.GetCore();
- switch (system_core) {
- default:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv7f-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv7k-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv7s-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("armv7m-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("armv7em-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 12:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 13:
- arch.SetTriple("thumbv7f-apple-" OSNAME);
- return true;
- case 14:
- arch.SetTriple("thumbv7k-apple-" OSNAME);
- return true;
- case 15:
- arch.SetTriple("thumbv7s-apple-" OSNAME);
- return true;
- case 16:
- arch.SetTriple("thumbv7m-apple-" OSNAME);
- return true;
- case 17:
- arch.SetTriple("thumbv7em-apple-" OSNAME);
- return true;
- case 18:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 19:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 20:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 21:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 22:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv7s-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv7f-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv7m-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv7em-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 12:
- arch.SetTriple("thumbv7f-apple-" OSNAME);
- return true;
- case 13:
- arch.SetTriple("thumbv7k-apple-" OSNAME);
- return true;
- case 14:
- arch.SetTriple("thumbv7s-apple-" OSNAME);
- return true;
- case 15:
- arch.SetTriple("thumbv7m-apple-" OSNAME);
- return true;
- case 16:
- arch.SetTriple("thumbv7em-apple-" OSNAME);
- return true;
- case 17:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 18:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 19:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 20:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 21:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7f:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7f-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumbv7f-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 12:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 13:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7k:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7k-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumbv7k-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 12:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 13:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7s:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7s-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumbv7s-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 12:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 13:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7m:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7m-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumbv7m-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 12:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 13:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7em:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7em-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumbv7em-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 12:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 13:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("thumbv7-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 10:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 11:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv6m:
- switch (idx) {
- case 0:
- arch.SetTriple("armv6m-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("thumbv6m-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 8:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 9:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv6:
- switch (idx) {
- case 0:
- arch.SetTriple("armv6-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("thumbv6-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 6:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 7:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv5:
- switch (idx) {
- case 0:
- arch.SetTriple("armv5-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("thumbv5-apple-" OSNAME);
- return true;
- case 4:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 5:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv4:
- switch (idx) {
- case 0:
- arch.SetTriple("armv4-apple-" OSNAME);
- return true;
- case 1:
- arch.SetTriple("arm-apple-" OSNAME);
- return true;
- case 2:
- arch.SetTriple("thumbv4t-apple-" OSNAME);
- return true;
- case 3:
- arch.SetTriple("thumb-apple-" OSNAME);
- return true;
- default:
- break;
- }
- break;
- }
- arch.Clear();
- return false;
-}
-
-// Return a directory path like /Applications/Xcode.app/Contents/Developer
-const char *PlatformDarwin::GetDeveloperDirectory() {
- std::lock_guard<std::mutex> guard(m_mutex);
- if (m_developer_directory.empty()) {
- bool developer_dir_path_valid = false;
- char developer_dir_path[PATH_MAX];
-
- // Get the lldb framework's file path, and if it exists, truncate some
- // components to only the developer directory path.
- FileSpec temp_file_spec = HostInfo::GetShlibDir();
- if (temp_file_spec) {
- if (temp_file_spec.GetPath(developer_dir_path,
- sizeof(developer_dir_path))) {
- // e.g.
- // /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework
- char *shared_frameworks =
- strstr(developer_dir_path, "/SharedFrameworks/LLDB.framework");
- if (shared_frameworks) {
- shared_frameworks[0] = '\0'; // truncate developer_dir_path at this point
- strncat (developer_dir_path, "/Developer", sizeof (developer_dir_path) - 1); // add /Developer on
- developer_dir_path_valid = true;
- } else {
- // e.g.
- // /Applications/Xcode.app/Contents/Developer/Toolchains/iOS11.2.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework
- char *developer_toolchains =
- strstr(developer_dir_path, "/Contents/Developer/Toolchains/");
- if (developer_toolchains) {
- developer_toolchains += sizeof ("/Contents/Developer") - 1;
- developer_toolchains[0] = '\0'; // truncate developer_dir_path at this point
- developer_dir_path_valid = true;
- }
- }
- }
- }
-
- if (!developer_dir_path_valid) {
- std::string xcode_dir_path;
- const char *xcode_select_prefix_dir = getenv("XCODE_SELECT_PREFIX_DIR");
- if (xcode_select_prefix_dir)
- xcode_dir_path.append(xcode_select_prefix_dir);
- xcode_dir_path.append("/usr/share/xcode-select/xcode_dir_path");
- temp_file_spec.SetFile(xcode_dir_path, FileSpec::Style::native);
- auto dir_buffer =
- FileSystem::Instance().CreateDataBuffer(temp_file_spec.GetPath());
- if (dir_buffer && dir_buffer->GetByteSize() > 0) {
- llvm::StringRef path_ref(dir_buffer->GetChars());
- // Trim tailing newlines and make sure there is enough room for a null
- // terminator.
- path_ref =
- path_ref.rtrim("\r\n").take_front(sizeof(developer_dir_path) - 1);
- ::memcpy(developer_dir_path, path_ref.data(), path_ref.size());
- developer_dir_path[path_ref.size()] = '\0';
- developer_dir_path_valid = true;
- }
- }
-
- if (!developer_dir_path_valid) {
- FileSpec xcode_select_cmd("/usr/bin/xcode-select");
- if (FileSystem::Instance().Exists(xcode_select_cmd)) {
- int exit_status = -1;
- int signo = -1;
- std::string command_output;
- Status error =
- Host::RunShellCommand("/usr/bin/xcode-select --print-path",
- NULL, // current working directory
- &exit_status, &signo, &command_output,
- std::chrono::seconds(2), // short timeout
- false); // don't run in a shell
- if (error.Success() && exit_status == 0 && !command_output.empty()) {
- const char *cmd_output_ptr = command_output.c_str();
- developer_dir_path[sizeof(developer_dir_path) - 1] = '\0';
- size_t i;
- for (i = 0; i < sizeof(developer_dir_path) - 1; i++) {
- if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' ||
- cmd_output_ptr[i] == '\0')
- break;
- developer_dir_path[i] = cmd_output_ptr[i];
- }
- developer_dir_path[i] = '\0';
-
- FileSpec devel_dir(developer_dir_path);
- if (FileSystem::Instance().IsDirectory(devel_dir)) {
- developer_dir_path_valid = true;
- }
- }
- }
- }
-
- if (developer_dir_path_valid) {
- temp_file_spec.SetFile(developer_dir_path, FileSpec::Style::native);
- if (FileSystem::Instance().Exists(temp_file_spec)) {
- m_developer_directory.assign(developer_dir_path);
- return m_developer_directory.c_str();
- }
- }
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_developer_directory.assign(1, '\0');
- }
-
- // We should have put a single NULL character into m_developer_directory or
- // it should have a valid path if the code gets here
- assert(m_developer_directory.empty() == false);
- if (m_developer_directory[0])
- return m_developer_directory.c_str();
- return NULL;
-}
-
-BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) {
- BreakpointSP bp_sp;
- static const char *g_bp_names[] = {
- "start_wqthread", "_pthread_wqthread", "_pthread_start",
- };
-
- static const char *g_bp_modules[] = {"libsystem_c.dylib",
- "libSystem.B.dylib"};
-
- FileSpecList bp_modules;
- for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++) {
- const char *bp_module = g_bp_modules[i];
- bp_modules.Append(FileSpec(bp_module));
- }
-
- bool internal = true;
- bool hardware = false;
- LazyBool skip_prologue = eLazyBoolNo;
- bp_sp = target.CreateBreakpoint(&bp_modules, NULL, g_bp_names,
- llvm::array_lengthof(g_bp_names),
- eFunctionNameTypeFull, eLanguageTypeUnknown,
- 0, skip_prologue, internal, hardware);
- bp_sp->SetBreakpointKind("thread-creation");
-
- return bp_sp;
-}
-
-int32_t
-PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
- const FileSpec &shell = launch_info.GetShell();
- if (!shell)
- return 1;
-
- std::string shell_string = shell.GetPath();
- const char *shell_name = strrchr(shell_string.c_str(), '/');
- if (shell_name == NULL)
- shell_name = shell_string.c_str();
- else
- shell_name++;
-
- if (strcmp(shell_name, "sh") == 0) {
- // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it
- // only does this if the COMMAND_MODE environment variable is set to
- // "legacy".
- if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy")
- return 2;
- return 1;
- } else if (strcmp(shell_name, "csh") == 0 ||
- strcmp(shell_name, "tcsh") == 0 ||
- strcmp(shell_name, "zsh") == 0) {
- // csh and tcsh always seem to re-exec themselves.
- return 2;
- } else
- return 1;
-}
-
-void PlatformDarwin::CalculateTrapHandlerSymbolNames() {
- m_trap_handlers.push_back(ConstString("_sigtramp"));
-}
-
-static const char *const sdk_strings[] = {
- "MacOSX", "iPhoneSimulator", "iPhoneOS",
-};
-
-static FileSpec CheckPathForXcode(const FileSpec &fspec) {
- if (FileSystem::Instance().Exists(fspec)) {
- const char substr[] = ".app/Contents";
-
- std::string path_to_shlib = fspec.GetPath();
- size_t pos = path_to_shlib.rfind(substr);
- if (pos != std::string::npos) {
- path_to_shlib.erase(pos + strlen(substr));
- FileSpec ret(path_to_shlib);
-
- FileSpec xcode_binary_path = ret;
- xcode_binary_path.AppendPathComponent("MacOS");
- xcode_binary_path.AppendPathComponent("Xcode");
-
- if (FileSystem::Instance().Exists(xcode_binary_path)) {
- return ret;
- }
- }
- }
- return FileSpec();
-}
-
-static FileSpec GetXcodeContentsPath() {
- static FileSpec g_xcode_filespec;
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() {
-
- FileSpec fspec;
-
- // First get the program file spec. If lldb.so or LLDB.framework is running
- // in a program and that program is Xcode, the path returned with be the
- // path to Xcode.app/Contents/MacOS/Xcode, so this will be the correct
- // Xcode to use.
- fspec = HostInfo::GetProgramFileSpec();
-
- if (fspec) {
- // Ignore the current binary if it is python.
- std::string basename_lower = fspec.GetFilename().GetCString();
- std::transform(basename_lower.begin(), basename_lower.end(),
- basename_lower.begin(), tolower);
- if (basename_lower != "python") {
- g_xcode_filespec = CheckPathForXcode(fspec);
- }
- }
-
- // Next check DEVELOPER_DIR environment variable
- if (!g_xcode_filespec) {
- const char *developer_dir_env_var = getenv("DEVELOPER_DIR");
- if (developer_dir_env_var && developer_dir_env_var[0]) {
- FileSpec developer_dir_spec = FileSpec(developer_dir_env_var);
- FileSystem::Instance().Resolve(developer_dir_spec);
- g_xcode_filespec = CheckPathForXcode(developer_dir_spec);
- }
-
- // Fall back to using "xcrun" to find the selected Xcode
- if (!g_xcode_filespec) {
- int status = 0;
- int signo = 0;
- std::string output;
- const char *command = "/usr/bin/xcode-select -p";
- lldb_private::Status error = Host::RunShellCommand(
- command, // shell command to run
- NULL, // current working directory
- &status, // Put the exit status of the process in here
- &signo, // Put the signal that caused the process to exit in here
- &output, // Get the output from the command and place it in this
- // string
- std::chrono::seconds(3));
- if (status == 0 && !output.empty()) {
- size_t first_non_newline = output.find_last_not_of("\r\n");
- if (first_non_newline != std::string::npos) {
- output.erase(first_non_newline + 1);
- }
- output.append("/..");
-
- g_xcode_filespec = CheckPathForXcode(FileSpec(output));
- }
- }
- }
- });
-
- return g_xcode_filespec;
-}
-
-bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type,
- llvm::VersionTuple version) {
- switch (sdk_type) {
- case SDKType::MacOSX:
- return version >= llvm::VersionTuple(10, 10);
- case SDKType::iPhoneOS:
- case SDKType::iPhoneSimulator:
- return version >= llvm::VersionTuple(8);
- }
-
- return false;
-}
-
-bool PlatformDarwin::SDKSupportsModules(SDKType desired_type,
- const FileSpec &sdk_path) {
- ConstString last_path_component = sdk_path.GetLastPathComponent();
-
- if (last_path_component) {
- const llvm::StringRef sdk_name = last_path_component.GetStringRef();
-
- if (!sdk_name.startswith(sdk_strings[desired_type]))
- return false;
- auto version_part =
- sdk_name.drop_front(strlen(sdk_strings[desired_type]));
- version_part.consume_back(".sdk");
-
- llvm::VersionTuple version;
- if (version.tryParse(version_part))
- return false;
- return SDKSupportsModules(desired_type, version);
- }
-
- return false;
-}
-
-FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator(
- void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) {
- SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);
-
- FileSpec spec(path);
- if (SDKSupportsModules(enumerator_info->sdk_type, spec)) {
- enumerator_info->found_path = spec;
- return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
- }
-
- return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
-}
-
-FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type,
- const FileSpec &sdks_spec) {
- // Look inside Xcode for the required installed iOS SDK version
-
- if (!FileSystem::Instance().IsDirectory(sdks_spec)) {
- return FileSpec();
- }
-
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = true; // include symlinks
-
- SDKEnumeratorInfo enumerator_info;
-
- enumerator_info.sdk_type = sdk_type;
-
- FileSystem::Instance().EnumerateDirectory(
- sdks_spec.GetPath(), find_directories, find_files, find_other,
- DirectoryEnumerator, &enumerator_info);
-
- if (FileSystem::Instance().IsDirectory(enumerator_info.found_path))
- return enumerator_info.found_path;
- else
- return FileSpec();
-}
-
-FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
- switch (sdk_type) {
- case SDKType::MacOSX:
- case SDKType::iPhoneSimulator:
- case SDKType::iPhoneOS:
- break;
- }
-
- FileSpec sdks_spec = GetXcodeContentsPath();
- sdks_spec.AppendPathComponent("Developer");
- sdks_spec.AppendPathComponent("Platforms");
-
- switch (sdk_type) {
- case SDKType::MacOSX:
- sdks_spec.AppendPathComponent("MacOSX.platform");
- break;
- case SDKType::iPhoneSimulator:
- sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
- break;
- case SDKType::iPhoneOS:
- sdks_spec.AppendPathComponent("iPhoneOS.platform");
- break;
- }
-
- sdks_spec.AppendPathComponent("Developer");
- sdks_spec.AppendPathComponent("SDKs");
-
- if (sdk_type == SDKType::MacOSX) {
- llvm::VersionTuple version = HostInfo::GetOSVersion();
-
- if (!version.empty()) {
- if (SDKSupportsModules(SDKType::MacOSX, version)) {
- // We slightly prefer the exact SDK for this machine. See if it is
- // there.
-
- FileSpec native_sdk_spec = sdks_spec;
- StreamString native_sdk_name;
- native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(),
- version.getMinor().getValueOr(0));
- native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
-
- if (FileSystem::Instance().Exists(native_sdk_spec)) {
- return native_sdk_spec;
- }
- }
- }
- }
-
- return FindSDKInXcodeForModules(sdk_type, sdks_spec);
-}
-
-std::tuple<llvm::VersionTuple, llvm::StringRef>
-PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
- llvm::StringRef build;
- llvm::StringRef version_str;
- llvm::StringRef build_str;
- std::tie(version_str, build_str) = dir.split(' ');
- llvm::VersionTuple version;
- if (!version.tryParse(version_str) ||
- build_str.empty()) {
- if (build_str.consume_front("(")) {
- size_t pos = build_str.find(')');
- build = build_str.slice(0, pos);
- }
- }
-
- return std::make_tuple(version, build);
-}
-
-void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- Target *target, std::vector<std::string> &options, SDKType sdk_type) {
- const std::vector<std::string> apple_arguments = {
- "-x", "objective-c++", "-fobjc-arc",
- "-fblocks", "-D_ISO646_H", "-D__ISO646_H"};
-
- options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
-
- StreamString minimum_version_option;
- bool use_current_os_version = false;
- switch (sdk_type) {
- case SDKType::iPhoneOS:
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- use_current_os_version = true;
-#else
- use_current_os_version = false;
-#endif
- break;
-
- case SDKType::iPhoneSimulator:
- use_current_os_version = false;
- break;
-
- case SDKType::MacOSX:
-#if defined(__i386__) || defined(__x86_64__)
- use_current_os_version = true;
-#else
- use_current_os_version = false;
-#endif
- break;
- }
-
- llvm::VersionTuple version;
- if (use_current_os_version)
- version = GetOSVersion();
- else if (target) {
- // Our OS doesn't match our executable so we need to get the min OS version
- // from the object file
- ModuleSP exe_module_sp = target->GetExecutableModule();
- if (exe_module_sp) {
- ObjectFile *object_file = exe_module_sp->GetObjectFile();
- if (object_file)
- version = object_file->GetMinimumOSVersion();
- }
- }
- // Only add the version-min options if we got a version from somewhere
- if (!version.empty()) {
- switch (sdk_type) {
- case SDKType::iPhoneOS:
- minimum_version_option.PutCString("-mios-version-min=");
- minimum_version_option.PutCString(version.getAsString());
- break;
- case SDKType::iPhoneSimulator:
- minimum_version_option.PutCString("-mios-simulator-version-min=");
- minimum_version_option.PutCString(version.getAsString());
- break;
- case SDKType::MacOSX:
- minimum_version_option.PutCString("-mmacosx-version-min=");
- minimum_version_option.PutCString(version.getAsString());
- }
- options.push_back(minimum_version_option.GetString());
- }
-
- FileSpec sysroot_spec;
- // Scope for mutex locker below
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- sysroot_spec = GetSDKDirectoryForModules(sdk_type);
- }
-
- if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
- options.push_back("-isysroot");
- options.push_back(sysroot_spec.GetPath());
- }
-}
-
-ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) {
- if (basename.IsEmpty())
- return basename;
-
- StreamString stream;
- stream.Printf("lib%s.dylib", basename.GetCString());
- return ConstString(stream.GetString());
-}
-
-llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) {
- if (process && strstr(GetPluginName().GetCString(), "-simulator")) {
- lldb_private::ProcessInstanceInfo proc_info;
- if (Host::GetProcessInfo(process->GetID(), proc_info)) {
- const Environment &env = proc_info.GetEnvironment();
-
- llvm::VersionTuple result;
- if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION")))
- return result;
-
- std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH");
- if (!dyld_root_path.empty()) {
- dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
- ApplePropertyList system_version_plist(dyld_root_path.c_str());
- std::string product_version;
- if (system_version_plist.GetValueAsString("ProductVersion",
- product_version)) {
- if (!result.tryParse(product_version))
- return result;
- }
- }
- }
- // For simulator platforms, do NOT call back through
- // Platform::GetOSVersion() as it might call Process::GetHostOSVersion()
- // which we don't want as it will be incorrect
- return llvm::VersionTuple();
- }
-
- return Platform::GetOSVersion(process);
-}
-
-lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
- // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled
- // in with
- // any executable directories that should be searched.
- static std::vector<FileSpec> g_executable_dirs;
-
- // Find the global list of directories that we will search for executables
- // once so we don't keep doing the work over and over.
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() {
-
- // When locating executables, trust the DEVELOPER_DIR first if it is set
- FileSpec xcode_contents_dir = GetXcodeContentsPath();
- if (xcode_contents_dir) {
- FileSpec xcode_lldb_resources = xcode_contents_dir;
- xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
- xcode_lldb_resources.AppendPathComponent("LLDB.framework");
- xcode_lldb_resources.AppendPathComponent("Resources");
- if (FileSystem::Instance().Exists(xcode_lldb_resources)) {
- FileSpec dir;
- dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
- g_executable_dirs.push_back(dir);
- }
- }
- });
-
- // Now search the global list of executable directories for the executable we
- // are looking for
- for (const auto &executable_dir : g_executable_dirs) {
- FileSpec executable_file;
- executable_file.GetDirectory() = executable_dir.GetDirectory();
- executable_file.GetFilename().SetCString(basename);
- if (FileSystem::Instance().Exists(executable_file))
- return executable_file;
- }
-
- return FileSpec();
-}
-
-lldb_private::Status
-PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) {
- // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if
- // the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't require
- // any specific value; rather, it just needs to exist). We will set it here
- // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set. Xcode
- // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
- // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
- // specifically want it unset.
- const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
- auto &env_vars = launch_info.GetEnvironment();
- if (!env_vars.count(disable_env_var)) {
- // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get
- // os_log and NSLog messages mirrored to the target process stderr.
- env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable");
- }
-
- // Let our parent class do the real launching.
- return PlatformPOSIX::LaunchProcess(launch_info);
-}
-
-lldb_private::Status
-PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec, Process *process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr, bool *did_create_ptr)
-{
- const FileSpec &platform_file = module_spec.GetFileSpec();
- // See if the file is present in any of the module_search_paths_ptr
- // directories.
- if (!module_sp && module_search_paths_ptr && platform_file) {
- // create a vector of all the file / directory names in platform_file e.g.
- // this might be
- // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
- //
- // We'll need to look in the module_search_paths_ptr directories for both
- // "UIFoundation" and "UIFoundation.framework" -- most likely the latter
- // will be the one we find there.
-
- FileSpec platform_pull_apart(platform_file);
- std::vector<std::string> path_parts;
- path_parts.push_back(
- platform_pull_apart.GetLastPathComponent().AsCString());
- while (platform_pull_apart.RemoveLastPathComponent()) {
- ConstString part = platform_pull_apart.GetLastPathComponent();
- path_parts.push_back(part.AsCString());
- }
- const size_t path_parts_size = path_parts.size();
-
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i) {
- Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log_verbose)
- log_verbose->Printf ("PlatformRemoteDarwinDevice::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
- // Create a new FileSpec with this module_search_paths_ptr plus just the
- // filename ("UIFoundation"), then the parent dir plus filename
- // ("UIFoundation.framework/UIFoundation") etc - up to four names (to
- // handle "Foo.framework/Contents/MacOS/Foo")
-
- for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
- FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
-
- // Add the components backwards. For
- // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts
- // is
- // [0] UIFoundation
- // [1] UIFoundation.framework
- // [2] PrivateFrameworks
- //
- // and if 'j' is 2, we want to append path_parts[1] and then
- // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the
- // module_search_paths_ptr path.
-
- for (int k = j; k >= 0; --k) {
- path_to_try.AppendPathComponent(path_parts[k]);
- }
-
- if (FileSystem::Instance().Exists(path_to_try)) {
- ModuleSpec new_module_spec(module_spec);
- new_module_spec.GetFileSpec() = path_to_try;
- Status new_error(Platform::GetSharedModule(
- new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp) {
- module_sp->SetPlatformFileSpec(path_to_try);
- return new_error;
- }
- }
- }
- }
- }
- return Status();
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
deleted file mode 100644
index f2dd9b1bc7782..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//===-- PlatformDarwin.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_PlatformDarwin_h_
-#define liblldb_PlatformDarwin_h_
-
-
-#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Utility/FileSpec.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/FileSystem.h"
-
-#include <string>
-#include <tuple>
-
-class PlatformDarwin : public PlatformPOSIX {
-public:
- PlatformDarwin(bool is_host);
-
- ~PlatformDarwin() override;
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Status
- ResolveSymbolFile(lldb_private::Target &target,
- const lldb_private::ModuleSpec &sym_spec,
- lldb_private::FileSpec &sym_file) override;
-
- lldb_private::FileSpecList LocateExecutableScriptingResources(
- lldb_private::Target *target, lldb_private::Module &module,
- lldb_private::Stream *feedback_stream) override;
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- size_t GetSoftwareBreakpointTrapOpcode(
- lldb_private::Target &target,
- lldb_private::BreakpointSite *bp_site) override;
-
- lldb::BreakpointSP
- SetThreadCreationBreakpoint(lldb_private::Target &target) override;
-
- bool ModuleIsExcludedForUnconstrainedSearches(
- lldb_private::Target &target, const lldb::ModuleSP &module_sp) override;
-
- bool ARMGetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch);
-
- bool x86GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch);
-
- int32_t GetResumeCountForLaunchInfo(
- lldb_private::ProcessLaunchInfo &launch_info) override;
-
- void CalculateTrapHandlerSymbolNames() override;
-
- llvm::VersionTuple
- GetOSVersion(lldb_private::Process *process = nullptr) override;
-
- bool SupportsModules() override { return true; }
-
- lldb_private::ConstString
- GetFullNameForDylib(lldb_private::ConstString basename) override;
-
- lldb_private::FileSpec LocateExecutable(const char *basename) override;
-
- lldb_private::Status
- LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
-
- static std::tuple<llvm::VersionTuple, llvm::StringRef>
- ParseVersionBuildDir(llvm::StringRef str);
-
- enum SDKType : unsigned {
- MacOSX = 0,
- iPhoneSimulator,
- iPhoneOS,
- };
-
-protected:
- void ReadLibdispatchOffsetsAddress(lldb_private::Process *process);
-
- void ReadLibdispatchOffsets(lldb_private::Process *process);
-
- virtual lldb_private::Status GetSharedModuleWithLocalCache(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
-
- static bool SDKSupportsModules(SDKType sdk_type, llvm::VersionTuple version);
-
- static bool SDKSupportsModules(SDKType desired_type,
- const lldb_private::FileSpec &sdk_path);
-
- struct SDKEnumeratorInfo {
- lldb_private::FileSpec found_path;
- SDKType sdk_type;
- };
-
- static lldb_private::FileSystem::EnumerateDirectoryResult
- DirectoryEnumerator(void *baton, llvm::sys::fs::file_type file_type,
- llvm::StringRef path);
-
- static lldb_private::FileSpec
- FindSDKInXcodeForModules(SDKType sdk_type,
- const lldb_private::FileSpec &sdks_spec);
-
- static lldb_private::FileSpec
- GetSDKDirectoryForModules(PlatformDarwin::SDKType sdk_type);
-
- void
- AddClangModuleCompilationOptionsForSDKType(lldb_private::Target *target,
- std::vector<std::string> &options,
- SDKType sdk_type);
-
- const char *GetDeveloperDirectory();
-
- lldb_private::Status
- FindBundleBinaryInExecSearchPaths (const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process,
- lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
-
- std::string m_developer_directory;
-
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformDarwin);
-};
-
-#endif // liblldb_PlatformDarwin_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
deleted file mode 100644
index 4c6d9459e225f..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ /dev/null
@@ -1,872 +0,0 @@
-//===-- PlatformDarwinKernel.cpp -----------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformDarwinKernel.h"
-
-#if defined(__APPLE__) // This Plugin uses the Mac-specific
- // source/Host/macosx/cfcpp utilities
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Interpreter/OptionValueFileSpecList.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Interpreter/Property.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "llvm/Support/FileSystem.h"
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "Host/macosx/cfcpp/CFCBundle.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformDarwinKernel::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(PlatformDarwinKernel::GetPluginNameStatic(),
- PlatformDarwinKernel::GetDescriptionStatic(),
- PlatformDarwinKernel::CreateInstance,
- PlatformDarwinKernel::DebuggerInitialize);
- }
-}
-
-void PlatformDarwinKernel::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformDarwinKernel::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
- const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformDarwinKernel::%s(force=%s, arch={%s,%s})",
- __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- // This is a special plugin that we don't want to activate just based on an
- // ArchSpec for normal userland debugging. It is only useful in kernel debug
- // sessions and the DynamicLoaderDarwinPlugin (or a user doing 'platform
- // select') will force the creation of this Platform plugin.
- if (!force) {
- if (log)
- log->Printf("PlatformDarwinKernel::%s() aborting creation of platform "
- "because force == false",
- __FUNCTION__);
- return PlatformSP();
- }
-
- bool create = force;
- LazyBool is_ios_debug_session = eLazyBoolCalculate;
-
- if (!create && arch && arch->IsValid()) {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
- // Only accept "unknown" for vendor if the host is Apple and it "unknown"
- // wasn't specified (it was just returned because it was NOT specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
- default:
- break;
- }
-
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::WatchOS:
- case llvm::Triple::TvOS:
- // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
- break;
- // Only accept "vendor" for vendor if the host is Apple and it "unknown"
- // wasn't specified (it was just returned because it was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
- default:
- create = false;
- break;
- }
- }
- }
- if (arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- is_ios_debug_session = eLazyBoolNo;
- break;
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb:
- is_ios_debug_session = eLazyBoolYes;
- break;
- default:
- is_ios_debug_session = eLazyBoolCalculate;
- break;
- }
- }
- if (create) {
- if (log)
- log->Printf("PlatformDarwinKernel::%s() creating platform", __FUNCTION__);
-
- return PlatformSP(new PlatformDarwinKernel(is_ios_debug_session));
- }
-
- if (log)
- log->Printf("PlatformDarwinKernel::%s() aborting creation of platform",
- __FUNCTION__);
-
- return PlatformSP();
-}
-
-lldb_private::ConstString PlatformDarwinKernel::GetPluginNameStatic() {
- static ConstString g_name("darwin-kernel");
- return g_name;
-}
-
-const char *PlatformDarwinKernel::GetDescriptionStatic() {
- return "Darwin Kernel platform plug-in.";
-}
-
-//------------------------------------------------------------------
-/// Code to handle the PlatformDarwinKernel settings
-//------------------------------------------------------------------
-
-static constexpr PropertyDefinition g_properties[] = {
- {"search-locally-for-kexts", OptionValue::eTypeBoolean, true, true, NULL,
- {}, "Automatically search for kexts on the local system when doing "
- "kernel debugging."},
- {"kext-directories", OptionValue::eTypeFileSpecList, false, 0, NULL, {},
- "Directories/KDKs to search for kexts in when starting a kernel debug "
- "session."}};
-
-enum { ePropertySearchForKexts = 0, ePropertyKextDirectories };
-
-class PlatformDarwinKernelProperties : public Properties {
-public:
- static ConstString &GetSettingName() {
- static ConstString g_setting_name("darwin-kernel");
- return g_setting_name;
- }
-
- PlatformDarwinKernelProperties() : Properties() {
- m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual ~PlatformDarwinKernelProperties() {}
-
- bool GetSearchForKexts() const {
- const uint32_t idx = ePropertySearchForKexts;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(
- NULL, idx, g_properties[idx].default_uint_value != 0);
- }
-
- FileSpecList &GetKextDirectories() const {
- const uint32_t idx = ePropertyKextDirectories;
- OptionValueFileSpecList *option_value =
- m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
- NULL, false, idx);
- assert(option_value);
- return option_value->GetCurrentValue();
- }
-};
-
-typedef std::shared_ptr<PlatformDarwinKernelProperties>
- PlatformDarwinKernelPropertiesSP;
-
-static const PlatformDarwinKernelPropertiesSP &GetGlobalProperties() {
- static PlatformDarwinKernelPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset(new PlatformDarwinKernelProperties());
- return g_settings_sp;
-}
-
-void PlatformDarwinKernel::DebuggerInitialize(
- lldb_private::Debugger &debugger) {
- if (!PluginManager::GetSettingForPlatformPlugin(
- debugger, PlatformDarwinKernelProperties::GetSettingName())) {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForPlatformPlugin(
- debugger, GetGlobalProperties()->GetValueProperties(),
- ConstString("Properties for the PlatformDarwinKernel plug-in."),
- is_global_setting);
- }
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformDarwinKernel::PlatformDarwinKernel(
- lldb_private::LazyBool is_ios_debug_session)
- : PlatformDarwin(false), // This is a remote platform
- m_name_to_kext_path_map_with_dsyms(),
- m_name_to_kext_path_map_without_dsyms(), m_search_directories(),
- m_search_directories_no_recursing(), m_kernel_binaries_with_dsyms(),
- m_kernel_binaries_without_dsyms(),
- m_ios_debug_session(is_ios_debug_session)
-
-{
- if (GetGlobalProperties()->GetSearchForKexts()) {
- CollectKextAndKernelDirectories();
- SearchForKextsAndKernelsRecursively();
- }
-}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformDarwinKernel::~PlatformDarwinKernel() {}
-
-void PlatformDarwinKernel::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- strm.Printf(" Debug session type: ");
- if (m_ios_debug_session == eLazyBoolYes)
- strm.Printf("iOS kernel debugging\n");
- else if (m_ios_debug_session == eLazyBoolNo)
- strm.Printf("Mac OS X kernel debugging\n");
- else
- strm.Printf("unknown kernel debugging\n");
-
- strm.Printf("Directories searched recursively:\n");
- const uint32_t num_kext_dirs = m_search_directories.size();
- for (uint32_t i = 0; i < num_kext_dirs; ++i) {
- strm.Printf("[%d] %s\n", i, m_search_directories[i].GetPath().c_str());
- }
-
- strm.Printf("Directories not searched recursively:\n");
- const uint32_t num_kext_dirs_no_recursion =
- m_search_directories_no_recursing.size();
- for (uint32_t i = 0; i < num_kext_dirs_no_recursion; i++) {
- strm.Printf("[%d] %s\n", i,
- m_search_directories_no_recursing[i].GetPath().c_str());
- }
-
- strm.Printf(" Number of kexts with dSYMs indexed: %d\n",
- (int)m_name_to_kext_path_map_with_dsyms.size());
- strm.Printf(" Number of kexts without dSYMs indexed: %d\n",
- (int)m_name_to_kext_path_map_without_dsyms.size());
- strm.Printf(" Number of Kernel binaries with dSYMs indexed: %d\n",
- (int)m_kernel_binaries_with_dsyms.size());
- strm.Printf(" Number of Kernel binaries without dSYMs indexed: %d\n",
- (int)m_kernel_binaries_without_dsyms.size());
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- log->Printf("\nkexts with dSYMs");
- for (auto pos : m_name_to_kext_path_map_with_dsyms) {
- log->Printf("%s", pos.second.GetPath().c_str());
- }
- log->Printf("\nkexts without dSYMs");
-
- for (auto pos : m_name_to_kext_path_map_without_dsyms) {
- log->Printf("%s", pos.second.GetPath().c_str());
- }
- log->Printf("\nkernels with dSYMS");
- for (auto fs : m_kernel_binaries_with_dsyms) {
- log->Printf("%s", fs.GetPath().c_str());
- }
- log->Printf("\nkernels without dSYMS");
- for (auto fs : m_kernel_binaries_without_dsyms) {
- log->Printf("%s", fs.GetPath().c_str());
- }
- log->Printf("\n");
- }
-}
-
-// Populate the m_search_directories vector with directories we should search
-// for kernel & kext binaries.
-
-void PlatformDarwinKernel::CollectKextAndKernelDirectories() {
- // Differentiate between "ios debug session" and "mac debug session" so we
- // don't index kext bundles that won't be used in this debug session. If
- // this is an ios kext debug session, looking in /System/Library/Extensions
- // is a waste of stat()s, for example.
-
- // DeveloperDirectory is something like
- // "/Applications/Xcode.app/Contents/Developer"
- std::string developer_dir = GetDeveloperDirectory();
- if (developer_dir.empty())
- developer_dir = "/Applications/Xcode.app/Contents/Developer";
-
- if (m_ios_debug_session != eLazyBoolNo) {
- AddSDKSubdirsToSearchPaths(developer_dir +
- "/Platforms/iPhoneOS.platform/Developer/SDKs");
- AddSDKSubdirsToSearchPaths(developer_dir +
- "/Platforms/AppleTVOS.platform/Developer/SDKs");
- AddSDKSubdirsToSearchPaths(developer_dir +
- "/Platforms/WatchOS.platform/Developer/SDKs");
- AddSDKSubdirsToSearchPaths(developer_dir +
- "/Platforms/BridgeOS.platform/Developer/SDKs");
- }
- if (m_ios_debug_session != eLazyBoolYes) {
- AddSDKSubdirsToSearchPaths(developer_dir +
- "/Platforms/MacOSX.platform/Developer/SDKs");
- }
-
- AddSDKSubdirsToSearchPaths("/Volumes/KernelDebugKit");
- AddSDKSubdirsToSearchPaths("/AppleInternal/Developer/KDKs");
- // The KDKs distributed from Apple installed on external developer systems
- // may be in directories like /Library/Developer/KDKs/KDK_10.10_14A298i.kdk
- AddSDKSubdirsToSearchPaths("/Library/Developer/KDKs");
-
- if (m_ios_debug_session != eLazyBoolNo) {
- }
- if (m_ios_debug_session != eLazyBoolYes) {
- AddRootSubdirsToSearchPaths(this, "/");
- }
-
- GetUserSpecifiedDirectoriesToSearch();
-
- // Add simple directory /Applications/Xcode.app/Contents/Developer/../Symbols
- FileSpec possible_dir(developer_dir + "/../Symbols");
- FileSystem::Instance().Resolve(possible_dir);
- if (FileSystem::Instance().IsDirectory(possible_dir))
- m_search_directories.push_back(possible_dir);
-
- // Add simple directory of the current working directory
- FileSpec cwd(".");
- FileSystem::Instance().Resolve(cwd);
- m_search_directories_no_recursing.push_back(cwd);
-}
-
-void PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch() {
- FileSpecList user_dirs(GetGlobalProperties()->GetKextDirectories());
- std::vector<FileSpec> possible_sdk_dirs;
-
- const uint32_t user_dirs_count = user_dirs.GetSize();
- for (uint32_t i = 0; i < user_dirs_count; i++) {
- FileSpec dir = user_dirs.GetFileSpecAtIndex(i);
- FileSystem::Instance().Resolve(dir);
- if (FileSystem::Instance().IsDirectory(dir)) {
- m_search_directories.push_back(dir);
- }
- }
-}
-
-void PlatformDarwinKernel::AddRootSubdirsToSearchPaths(
- PlatformDarwinKernel *thisp, const std::string &dir) {
- const char *subdirs[] = {
- "/System/Library/Extensions", "/Library/Extensions",
- "/System/Library/Kernels",
- "/System/Library/Extensions/KDK", // this one probably only exist in
- // /AppleInternal/Developer/KDKs/*.kdk/...
- nullptr};
- for (int i = 0; subdirs[i] != nullptr; i++) {
- FileSpec testdir(dir + subdirs[i]);
- FileSystem::Instance().Resolve(testdir);
- if (FileSystem::Instance().IsDirectory(testdir))
- thisp->m_search_directories.push_back(testdir);
- }
-
- // Look for kernel binaries in the top level directory, without any recursion
- thisp->m_search_directories_no_recursing.push_back(FileSpec(dir + "/"));
-}
-
-// Given a directory path dir, look for any subdirs named *.kdk and *.sdk
-void PlatformDarwinKernel::AddSDKSubdirsToSearchPaths(const std::string &dir) {
- // Look for *.kdk and *.sdk in dir
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
- FileSystem::Instance().EnumerateDirectory(
- dir.c_str(), find_directories, find_files, find_other,
- FindKDKandSDKDirectoriesInDirectory, this);
-}
-
-// Helper function to find *.sdk and *.kdk directories in a given directory.
-FileSystem::EnumerateDirectoryResult
-PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory(
- void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
- static ConstString g_sdk_suffix = ConstString(".sdk");
- static ConstString g_kdk_suffix = ConstString(".kdk");
-
- PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
- FileSpec file_spec(path);
- if (ft == llvm::sys::fs::file_type::directory_file &&
- (file_spec.GetFileNameExtension() == g_sdk_suffix ||
- file_spec.GetFileNameExtension() == g_kdk_suffix)) {
- AddRootSubdirsToSearchPaths(thisp, file_spec.GetPath());
- }
- return FileSystem::eEnumerateDirectoryResultNext;
-}
-
-// Recursively search trough m_search_directories looking for kext and kernel
-// binaries, adding files found to the appropriate lists.
-void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
- const uint32_t num_dirs = m_search_directories.size();
- for (uint32_t i = 0; i < num_dirs; i++) {
- const FileSpec &dir = m_search_directories[i];
- const bool find_directories = true;
- const bool find_files = true;
- const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s.
- FileSystem::Instance().EnumerateDirectory(
- dir.GetPath().c_str(), find_directories, find_files, find_other,
- GetKernelsAndKextsInDirectoryWithRecursion, this);
- }
- const uint32_t num_dirs_no_recurse = m_search_directories_no_recursing.size();
- for (uint32_t i = 0; i < num_dirs_no_recurse; i++) {
- const FileSpec &dir = m_search_directories_no_recursing[i];
- const bool find_directories = true;
- const bool find_files = true;
- const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s.
- FileSystem::Instance().EnumerateDirectory(
- dir.GetPath().c_str(), find_directories, find_files, find_other,
- GetKernelsAndKextsInDirectoryNoRecursion, this);
- }
-}
-
-// We're only doing a filename match here. We won't try opening the file to
-// see if it's really a kernel or not until we need to find a kernel of a given
-// UUID. There's no cheap way to find the UUID of a file (or if it's a Mach-O
-// binary at all) without creating a whole Module for the file and throwing it
-// away if it's not wanted.
-//
-// Recurse into any subdirectories found.
-
-FileSystem::EnumerateDirectoryResult
-PlatformDarwinKernel::GetKernelsAndKextsInDirectoryWithRecursion(
- void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
- return GetKernelsAndKextsInDirectoryHelper(baton, ft, path, true);
-}
-
-FileSystem::EnumerateDirectoryResult
-PlatformDarwinKernel::GetKernelsAndKextsInDirectoryNoRecursion(
- void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
- return GetKernelsAndKextsInDirectoryHelper(baton, ft, path, false);
-}
-
-FileSystem::EnumerateDirectoryResult
-PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
- void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path,
- bool recurse) {
- static ConstString g_kext_suffix = ConstString(".kext");
- static ConstString g_dsym_suffix = ConstString(".dSYM");
- static ConstString g_bundle_suffix = ConstString("Bundle");
-
- FileSpec file_spec(path);
- ConstString file_spec_extension = file_spec.GetFileNameExtension();
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- Log *log_verbose(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM | LLDB_LOG_OPTION_VERBOSE));
-
- if (log_verbose)
- log_verbose->Printf ("PlatformDarwinKernel examining '%s'", file_spec.GetPath().c_str());
-
- PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
- if (ft == llvm::sys::fs::file_type::regular_file ||
- ft == llvm::sys::fs::file_type::symlink_file) {
- ConstString filename = file_spec.GetFilename();
- if ((strncmp(filename.GetCString(), "kernel", 6) == 0 ||
- strncmp(filename.GetCString(), "mach", 4) == 0) &&
- file_spec_extension != g_dsym_suffix) {
- if (KernelHasdSYMSibling(file_spec))
- {
- if (log)
- {
- log->Printf ("PlatformDarwinKernel registering kernel binary '%s' with dSYM sibling", file_spec.GetPath().c_str());
- }
- thisp->m_kernel_binaries_with_dsyms.push_back(file_spec);
- }
- else
- {
- if (log)
- {
- log->Printf ("PlatformDarwinKernel registering kernel binary '%s', no dSYM", file_spec.GetPath().c_str());
- }
- thisp->m_kernel_binaries_without_dsyms.push_back(file_spec);
- }
- return FileSystem::eEnumerateDirectoryResultNext;
- }
- } else if (ft == llvm::sys::fs::file_type::directory_file &&
- file_spec_extension == g_kext_suffix) {
- AddKextToMap(thisp, file_spec);
- // Look to see if there is a PlugIns subdir with more kexts
- FileSpec contents_plugins(file_spec.GetPath() + "/Contents/PlugIns");
- std::string search_here_too;
- if (FileSystem::Instance().IsDirectory(contents_plugins)) {
- search_here_too = contents_plugins.GetPath();
- } else {
- FileSpec plugins(file_spec.GetPath() + "/PlugIns");
- if (FileSystem::Instance().IsDirectory(plugins)) {
- search_here_too = plugins.GetPath();
- }
- }
-
- if (!search_here_too.empty()) {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
- FileSystem::Instance().EnumerateDirectory(
- search_here_too.c_str(), find_directories, find_files, find_other,
- recurse ? GetKernelsAndKextsInDirectoryWithRecursion
- : GetKernelsAndKextsInDirectoryNoRecursion,
- baton);
- }
- return FileSystem::eEnumerateDirectoryResultNext;
- }
- // Don't recurse into dSYM/kext/bundle directories
- if (recurse && file_spec_extension != g_dsym_suffix &&
- file_spec_extension != g_kext_suffix &&
- file_spec_extension != g_bundle_suffix) {
- if (log_verbose)
- log_verbose->Printf ("PlatformDarwinKernel descending into directory '%s'", file_spec.GetPath().c_str());
- return FileSystem::eEnumerateDirectoryResultEnter;
- } else {
- return FileSystem::eEnumerateDirectoryResultNext;
- }
-}
-
-void PlatformDarwinKernel::AddKextToMap(PlatformDarwinKernel *thisp,
- const FileSpec &file_spec) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- CFCBundle bundle(file_spec.GetPath().c_str());
- CFStringRef bundle_id(bundle.GetIdentifier());
- if (bundle_id && CFGetTypeID(bundle_id) == CFStringGetTypeID()) {
- char bundle_id_buf[PATH_MAX];
- if (CFStringGetCString(bundle_id, bundle_id_buf, sizeof(bundle_id_buf),
- kCFStringEncodingUTF8)) {
- ConstString bundle_conststr(bundle_id_buf);
- if (KextHasdSYMSibling(file_spec))
- {
- if (log)
- {
- log->Printf ("PlatformDarwinKernel registering kext binary '%s' with dSYM sibling", file_spec.GetPath().c_str());
- }
- thisp->m_name_to_kext_path_map_with_dsyms.insert(
- std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
- }
- else
- {
- if (log)
- {
- log->Printf ("PlatformDarwinKernel registering kext binary '%s', no dSYM", file_spec.GetPath().c_str());
- }
- thisp->m_name_to_kext_path_map_without_dsyms.insert(
- std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
- }
- }
- }
-}
-
-// Given a FileSpec of /dir/dir/foo.kext
-// Return true if any of these exist:
-// /dir/dir/foo.kext.dSYM
-// /dir/dir/foo.kext/Contents/MacOS/foo.dSYM
-// /dir/dir/foo.kext/foo.dSYM
-bool PlatformDarwinKernel::KextHasdSYMSibling(
- const FileSpec &kext_bundle_filepath) {
- FileSpec dsym_fspec = kext_bundle_filepath;
- std::string filename = dsym_fspec.GetFilename().AsCString();
- filename += ".dSYM";
- dsym_fspec.GetFilename() = ConstString(filename);
- if (FileSystem::Instance().IsDirectory(dsym_fspec)) {
- return true;
- }
- // Should probably get the CFBundleExecutable here or call
- // CFBundleCopyExecutableURL
-
- // Look for a deep bundle foramt
- ConstString executable_name =
- kext_bundle_filepath.GetFileNameStrippingExtension();
- std::string deep_bundle_str =
- kext_bundle_filepath.GetPath() + "/Contents/MacOS/";
- deep_bundle_str += executable_name.AsCString();
- deep_bundle_str += ".dSYM";
- dsym_fspec.SetFile(deep_bundle_str, FileSpec::Style::native);
- FileSystem::Instance().Resolve(dsym_fspec);
- if (FileSystem::Instance().IsDirectory(dsym_fspec)) {
- return true;
- }
-
- // look for a shallow bundle format
- //
- std::string shallow_bundle_str = kext_bundle_filepath.GetPath() + "/";
- shallow_bundle_str += executable_name.AsCString();
- shallow_bundle_str += ".dSYM";
- dsym_fspec.SetFile(shallow_bundle_str, FileSpec::Style::native);
- FileSystem::Instance().Resolve(dsym_fspec);
- return FileSystem::Instance().IsDirectory(dsym_fspec);
-}
-
-// Given a FileSpec of /dir/dir/mach.development.t7004 Return true if a dSYM
-// exists next to it:
-// /dir/dir/mach.development.t7004.dSYM
-bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) {
- FileSpec kernel_dsym = kernel_binary;
- std::string filename = kernel_binary.GetFilename().AsCString();
- filename += ".dSYM";
- kernel_dsym.GetFilename() = ConstString(filename);
- return FileSystem::Instance().IsDirectory(kernel_dsym);
-}
-
-Status PlatformDarwinKernel::GetSharedModule(
- const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) {
- Status error;
- module_sp.reset();
- const FileSpec &platform_file = module_spec.GetFileSpec();
-
- // Treat the file's path as a kext bundle ID (e.g.
- // "com.apple.driver.AppleIRController") and search our kext index.
- std::string kext_bundle_id = platform_file.GetPath();
- if (!kext_bundle_id.empty()) {
- ConstString kext_bundle_cs(kext_bundle_id.c_str());
-
- // First look through the kext bundles that had a dsym next to them
- if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle_cs) > 0) {
- for (BundleIDToKextIterator it =
- m_name_to_kext_path_map_with_dsyms.begin();
- it != m_name_to_kext_path_map_with_dsyms.end(); ++it) {
- if (it->first == kext_bundle_cs) {
- error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
- module_spec.GetArchitecture(),
- module_sp);
- if (module_sp.get()) {
- return error;
- }
- }
- }
- }
-
- // Give the generic methods, including possibly calling into DebugSymbols
- // framework on macOS systems, a chance.
- error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- if (error.Success() && module_sp.get()) {
- return error;
- }
-
- // Lastly, look through the kext binarys without dSYMs
- if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle_cs) > 0) {
- for (BundleIDToKextIterator it =
- m_name_to_kext_path_map_without_dsyms.begin();
- it != m_name_to_kext_path_map_without_dsyms.end(); ++it) {
- if (it->first == kext_bundle_cs) {
- error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
- module_spec.GetArchitecture(),
- module_sp);
- if (module_sp.get()) {
- return error;
- }
- }
- }
- }
- }
-
- if (kext_bundle_id == "mach_kernel" && module_spec.GetUUID().IsValid()) {
- // First try all kernel binaries that have a dSYM next to them
- for (auto possible_kernel : m_kernel_binaries_with_dsyms) {
- if (FileSystem::Instance().Exists(possible_kernel)) {
- ModuleSpec kern_spec(possible_kernel);
- kern_spec.GetUUID() = module_spec.GetUUID();
- ModuleSP module_sp(new Module(kern_spec));
- if (module_sp && module_sp->GetObjectFile() &&
- module_sp->MatchesModuleSpec(kern_spec)) {
- // module_sp is an actual kernel binary we want to add.
- if (process) {
- process->GetTarget().GetImages().AppendIfNeeded(module_sp);
- error.Clear();
- return error;
- } else {
- error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL,
- NULL, NULL);
- if (module_sp && module_sp->GetObjectFile() &&
- module_sp->GetObjectFile()->GetType() !=
- ObjectFile::Type::eTypeCoreFile) {
- return error;
- }
- module_sp.reset();
- }
- }
- }
- }
-
- // Give the generic methods, including possibly calling into DebugSymbols
- // framework on macOS systems, a chance.
- error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- if (error.Success() && module_sp.get()) {
- return error;
- }
-
- // Next try all kernel binaries that don't have a dSYM
- for (auto possible_kernel : m_kernel_binaries_without_dsyms) {
- if (FileSystem::Instance().Exists(possible_kernel)) {
- ModuleSpec kern_spec(possible_kernel);
- kern_spec.GetUUID() = module_spec.GetUUID();
- ModuleSP module_sp(new Module(kern_spec));
- if (module_sp && module_sp->GetObjectFile() &&
- module_sp->MatchesModuleSpec(kern_spec)) {
- // module_sp is an actual kernel binary we want to add.
- if (process) {
- process->GetTarget().GetImages().AppendIfNeeded(module_sp);
- error.Clear();
- return error;
- } else {
- error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL,
- NULL, NULL);
- if (module_sp && module_sp->GetObjectFile() &&
- module_sp->GetObjectFile()->GetType() !=
- ObjectFile::Type::eTypeCoreFile) {
- return error;
- }
- module_sp.reset();
- }
- }
- }
- }
- }
-
- return error;
-}
-
-std::vector<lldb_private::FileSpec>
-PlatformDarwinKernel::SearchForExecutablesRecursively(const std::string &dir) {
- std::vector<FileSpec> executables;
- std::error_code EC;
- for (llvm::sys::fs::recursive_directory_iterator it(dir.c_str(), EC),
- end;
- it != end && !EC; it.increment(EC)) {
- auto status = it->status();
- if (!status)
- break;
- if (llvm::sys::fs::is_regular_file(*status) &&
- llvm::sys::fs::can_execute(it->path()))
- executables.emplace_back(it->path());
- }
- return executables;
-}
-
-Status PlatformDarwinKernel::ExamineKextForMatchingUUID(
- const FileSpec &kext_bundle_path, const lldb_private::UUID &uuid,
- const ArchSpec &arch, ModuleSP &exe_module_sp) {
- for (const auto &exe_file :
- SearchForExecutablesRecursively(kext_bundle_path.GetPath())) {
- if (FileSystem::Instance().Exists(exe_file)) {
- ModuleSpec exe_spec(exe_file);
- exe_spec.GetUUID() = uuid;
- if (!uuid.IsValid()) {
- exe_spec.GetArchitecture() = arch;
- }
-
- // First try to create a ModuleSP with the file / arch and see if the UUID
- // matches. If that fails (this exec file doesn't have the correct uuid),
- // don't call GetSharedModule (which may call in to the DebugSymbols
- // framework and therefore can be slow.)
- ModuleSP module_sp(new Module(exe_spec));
- if (module_sp && module_sp->GetObjectFile() &&
- module_sp->MatchesModuleSpec(exe_spec)) {
- Status error = ModuleList::GetSharedModule(exe_spec, exe_module_sp,
- NULL, NULL, NULL);
- if (exe_module_sp && exe_module_sp->GetObjectFile()) {
- return error;
- }
- }
- exe_module_sp.reset();
- }
- }
-
- return {};
-}
-
-bool PlatformDarwinKernel::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- return ARMGetSupportedArchitectureAtIndex(idx, arch);
-#else
- return x86GetSupportedArchitectureAtIndex(idx, arch);
-#endif
-}
-
-void PlatformDarwinKernel::CalculateTrapHandlerSymbolNames() {
- m_trap_handlers.push_back(ConstString("trap_from_kernel"));
- m_trap_handlers.push_back(ConstString("hndl_machine_check"));
- m_trap_handlers.push_back(ConstString("hndl_double_fault"));
- m_trap_handlers.push_back(ConstString("hndl_allintrs"));
- m_trap_handlers.push_back(ConstString("hndl_alltraps"));
- m_trap_handlers.push_back(ConstString("interrupt"));
- m_trap_handlers.push_back(ConstString("fleh_prefabt"));
- m_trap_handlers.push_back(ConstString("ExceptionVectorsBase"));
- m_trap_handlers.push_back(ConstString("ExceptionVectorsTable"));
- m_trap_handlers.push_back(ConstString("fleh_undef"));
- m_trap_handlers.push_back(ConstString("fleh_dataabt"));
- m_trap_handlers.push_back(ConstString("fleh_irq"));
- m_trap_handlers.push_back(ConstString("fleh_decirq"));
- m_trap_handlers.push_back(ConstString("fleh_fiq_generic"));
- m_trap_handlers.push_back(ConstString("fleh_dec"));
-}
-
-#else // __APPLE__
-
-// Since DynamicLoaderDarwinKernel is compiled in for all systems, and relies
-// on PlatformDarwinKernel for the plug-in name, we compile just the plug-in
-// name in here to avoid issues. We are tracking an internal bug to resolve
-// this issue by either not compiling in DynamicLoaderDarwinKernel for non-
-// apple builds, or to make PlatformDarwinKernel build on all systems.
-// PlatformDarwinKernel is currently not compiled on other platforms due to the
-// use of the Mac-specific source/Host/macosx/cfcpp utilities.
-
-lldb_private::ConstString PlatformDarwinKernel::GetPluginNameStatic() {
- static lldb_private::ConstString g_name("darwin-kernel");
- return g_name;
-}
-
-#endif // __APPLE__
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
deleted file mode 100644
index 201c3dff17954..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
+++ /dev/null
@@ -1,208 +0,0 @@
-//===-- PlatformDarwinKernel.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_PlatformDarwinKernel_h_
-#define liblldb_PlatformDarwinKernel_h_
-
-#include "lldb/Utility/ConstString.h"
-
-#if defined(__APPLE__) // This Plugin uses the Mac-specific
- // source/Host/macosx/cfcpp utilities
-
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/Support/FileSystem.h"
-
-#include "PlatformDarwin.h"
-
-class PlatformDarwinKernel : public PlatformDarwin {
-public:
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void DebuggerInitialize(lldb_private::Debugger &debugger);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformDarwinKernel(lldb_private::LazyBool is_ios_debug_session);
-
- virtual ~PlatformDarwinKernel();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- bool SupportsModules() override { return false; }
-
- void CalculateTrapHandlerSymbolNames() override;
-
-protected:
- // Map from kext bundle ID ("com.apple.filesystems.exfat") to FileSpec for the
- // kext bundle on
- // the host ("/System/Library/Extensions/exfat.kext/Contents/Info.plist").
- typedef std::multimap<lldb_private::ConstString, lldb_private::FileSpec>
- BundleIDToKextMap;
- typedef BundleIDToKextMap::iterator BundleIDToKextIterator;
-
- typedef std::vector<lldb_private::FileSpec> KernelBinaryCollection;
-
- // Array of directories that were searched for kext bundles (used only for
- // reporting to user)
- typedef std::vector<lldb_private::FileSpec> DirectoriesSearchedCollection;
- typedef DirectoriesSearchedCollection::iterator DirectoriesSearchedIterator;
-
- // Populate m_search_directories and m_search_directories_no_recursing vectors
- // of directories
- void CollectKextAndKernelDirectories();
-
- void GetUserSpecifiedDirectoriesToSearch();
-
- static void AddRootSubdirsToSearchPaths(PlatformDarwinKernel *thisp,
- const std::string &dir);
-
- void AddSDKSubdirsToSearchPaths(const std::string &dir);
-
- static lldb_private::FileSystem::EnumerateDirectoryResult
- FindKDKandSDKDirectoriesInDirectory(void *baton, llvm::sys::fs::file_type ft,
- llvm::StringRef path);
-
- void SearchForKextsAndKernelsRecursively();
-
- static lldb_private::FileSystem::EnumerateDirectoryResult
- GetKernelsAndKextsInDirectoryWithRecursion(void *baton,
- llvm::sys::fs::file_type ft,
- llvm::StringRef path);
-
- static lldb_private::FileSystem::EnumerateDirectoryResult
- GetKernelsAndKextsInDirectoryNoRecursion(void *baton,
- llvm::sys::fs::file_type ft,
- llvm::StringRef path);
-
- static lldb_private::FileSystem::EnumerateDirectoryResult
- GetKernelsAndKextsInDirectoryHelper(void *baton, llvm::sys::fs::file_type ft,
- llvm::StringRef path, bool recurse);
-
- static std::vector<lldb_private::FileSpec>
- SearchForExecutablesRecursively(const std::string &dir);
-
- static void AddKextToMap(PlatformDarwinKernel *thisp,
- const lldb_private::FileSpec &file_spec);
-
- // Returns true if there is a .dSYM bundle next to the kext, or next to the
- // binary inside the kext.
- static bool
- KextHasdSYMSibling(const lldb_private::FileSpec &kext_bundle_filepath);
-
- // Returns true if there is a .dSYM bundle next to the kernel
- static bool
- KernelHasdSYMSibling(const lldb_private::FileSpec &kext_bundle_filepath);
-
- lldb_private::Status
- ExamineKextForMatchingUUID(const lldb_private::FileSpec &kext_bundle_path,
- const lldb_private::UUID &uuid,
- const lldb_private::ArchSpec &arch,
- lldb::ModuleSP &exe_module_sp);
-
- // Most of the ivars are assembled under FileSystem::EnumerateDirectory calls
- // where the
- // function being called for each file/directory must be static. We'll pass a
- // this pointer
- // as a baton and access the ivars directly. Toss-up whether this should just
- // be a struct
- // at this point.
-
-public:
- BundleIDToKextMap m_name_to_kext_path_map_with_dsyms; // multimap of
- // CFBundleID to
- // FileSpec on local
- // filesystem, kexts
- // with dSYMs next to
- // them
- BundleIDToKextMap m_name_to_kext_path_map_without_dsyms; // multimap of
- // CFBundleID to
- // FileSpec on local
- // filesystem, kexts
- // without dSYMs next
- // to them
- DirectoriesSearchedCollection
- m_search_directories; // list of directories we search for kexts/kernels
- DirectoriesSearchedCollection
- m_search_directories_no_recursing; // list of directories we search for
- // kexts/kernels, no recursion
- KernelBinaryCollection m_kernel_binaries_with_dsyms; // list of kernel
- // binaries we found on
- // local filesystem,
- // without dSYMs next to
- // them
- KernelBinaryCollection m_kernel_binaries_without_dsyms; // list of kernel
- // binaries we found
- // on local
- // filesystem, with
- // dSYMs next to them
- lldb_private::LazyBool m_ios_debug_session;
-
- DISALLOW_COPY_AND_ASSIGN(PlatformDarwinKernel);
-};
-
-#else // __APPLE__
-
-// Since DynamicLoaderDarwinKernel is compiled in for all systems, and relies on
-// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name
-// in
-// here to avoid issues. We are tracking an internal bug to resolve this issue
-// by
-// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to
-// make
-// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently
-// not
-// compiled on other platforms due to the use of the Mac-specific
-// source/Host/macosx/cfcpp utilities.
-
-class PlatformDarwinKernel {
-public:
- static lldb_private::ConstString GetPluginNameStatic();
-};
-
-#endif // __APPLE__
-
-#endif // liblldb_PlatformDarwinKernel_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
deleted file mode 100644
index 4117231c308a7..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-//===-- PlatformMacOSX.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformMacOSX.h"
-#include "lldb/Host/Config.h"
-
-
-#include <sstream>
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-static uint32_t g_initialize_count = 0;
-
-void PlatformMacOSX::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
-#if defined(__APPLE__)
- PlatformSP default_platform_sp(new PlatformMacOSX(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform(default_platform_sp);
-#endif
- PluginManager::RegisterPlugin(PlatformMacOSX::GetPluginNameStatic(false),
- PlatformMacOSX::GetDescriptionStatic(false),
- PlatformMacOSX::CreateInstance);
- }
-}
-
-void PlatformMacOSX::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformMacOSX::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformMacOSX::%s(force=%s, arch={%s,%s})", __FUNCTION__,
- force ? "true" : "false", arch_name, triple_cstr);
- }
-
- // The only time we create an instance is when we are creating a remote
- // macosx platform
- const bool is_host = false;
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for vendor if the host is Apple and it "unknown"
- // wasn't specified (it was just returned because it was NOT specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-#endif
- default:
- break;
- }
-
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
- // historical reasons
- case llvm::Triple::MacOSX:
- break;
-#if defined(__APPLE__)
- // Only accept "vendor" for vendor if the host is Apple and it "unknown"
- // wasn't specified (it was just returned because it was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
- default:
- create = false;
- break;
- }
- }
- }
- if (create) {
- if (log)
- log->Printf("PlatformMacOSX::%s() creating platform", __FUNCTION__);
- return PlatformSP(new PlatformMacOSX(is_host));
- }
-
- if (log)
- log->Printf("PlatformMacOSX::%s() aborting creation of platform",
- __FUNCTION__);
-
- return PlatformSP();
-}
-
-lldb_private::ConstString PlatformMacOSX::GetPluginNameStatic(bool is_host) {
- if (is_host) {
- static ConstString g_host_name(Platform::GetHostPlatformName());
- return g_host_name;
- } else {
- static ConstString g_remote_name("remote-macosx");
- return g_remote_name;
- }
-}
-
-const char *PlatformMacOSX::GetDescriptionStatic(bool is_host) {
- if (is_host)
- return "Local Mac OS X user platform plug-in.";
- else
- return "Remote Mac OS X user platform plug-in.";
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformMacOSX::PlatformMacOSX(bool is_host) : PlatformDarwin(is_host) {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformMacOSX::~PlatformMacOSX() {}
-
-ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
- ModuleSP exe_module_sp(target.GetExecutableModule());
- if (exe_module_sp) {
- ObjectFile *objfile = exe_module_sp->GetObjectFile();
- if (objfile) {
- std::string xcode_contents_path;
- std::string default_xcode_sdk;
- FileSpec fspec;
- uint32_t versions[2];
- if (objfile->GetSDKVersion(versions, sizeof(versions))) {
- fspec = HostInfo::GetShlibDir();
- if (fspec) {
- std::string path;
- xcode_contents_path = fspec.GetPath();
- size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
- if (pos != std::string::npos) {
- // LLDB.framework is inside an Xcode app bundle, we can locate the
- // SDK from here
- xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/"));
- } else {
- xcode_contents_path.clear();
- // Use the selected Xcode
- int status = 0;
- int signo = 0;
- std::string output;
- const char *command = "xcrun -sdk macosx --show-sdk-path";
- lldb_private::Status error = RunShellCommand(
- command, // shell command to run
- NULL, // current working directory
- &status, // Put the exit status of the process in here
- &signo, // Put the signal that caused the process to exit in
- // here
- &output, // Get the output from the command and place it in this
- // string
- std::chrono::seconds(3));
- if (status == 0 && !output.empty()) {
- size_t first_non_newline = output.find_last_not_of("\r\n");
- if (first_non_newline != std::string::npos)
- output.erase(first_non_newline + 1);
- default_xcode_sdk = output;
-
- pos = default_xcode_sdk.find("/Xcode.app/Contents/");
- if (pos != std::string::npos)
- xcode_contents_path = default_xcode_sdk.substr(
- 0, pos + strlen("/Xcode.app/Contents/"));
- }
- }
- }
-
- if (!xcode_contents_path.empty()) {
- StreamString sdk_path;
- sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/"
- "SDKs/MacOSX%u.%u.sdk",
- xcode_contents_path.c_str(), versions[0],
- versions[1]);
- fspec.SetFile(sdk_path.GetString(), FileSpec::Style::native);
- if (FileSystem::Instance().Exists(fspec))
- return ConstString(sdk_path.GetString());
- }
-
- if (!default_xcode_sdk.empty()) {
- fspec.SetFile(default_xcode_sdk, FileSpec::Style::native);
- if (FileSystem::Instance().Exists(fspec))
- return ConstString(default_xcode_sdk);
- }
- }
- }
- }
- return ConstString();
-}
-
-Status PlatformMacOSX::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- if (IsRemote()) {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
- local_file);
- }
-
- // Default to the local case
- local_file = platform_file;
- return Status();
-}
-
-lldb_private::Status
-PlatformMacOSX::GetFileWithUUID(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file) {
- if (IsRemote() && m_remote_platform_sp) {
- std::string local_os_build;
-#if !defined(__linux__)
- HostInfo::GetOSBuildString(local_os_build);
-#endif
- std::string remote_os_build;
- m_remote_platform_sp->GetOSBuildString(remote_os_build);
- if (local_os_build == remote_os_build) {
- // same OS version: the local file is good enough
- local_file = platform_file;
- return Status();
- } else {
- // try to find the file in the cache
- std::string cache_path(GetLocalCacheDirectory());
- std::string module_path(platform_file.GetPath());
- cache_path.append(module_path);
- FileSpec module_cache_spec(cache_path);
- if (FileSystem::Instance().Exists(module_cache_spec)) {
- local_file = module_cache_spec;
- return Status();
- }
- // bring in the remote module file
- FileSpec module_cache_folder =
- module_cache_spec.CopyByRemovingLastPathComponent();
- // try to make the local directory first
- Status err(
- llvm::sys::fs::create_directory(module_cache_folder.GetPath()));
- if (err.Fail())
- return err;
- err = GetFile(platform_file, module_cache_spec);
- if (err.Fail())
- return err;
- if (FileSystem::Instance().Exists(module_cache_spec)) {
- local_file = module_cache_spec;
- return Status();
- } else
- return Status("unable to obtain valid module file");
- }
- }
- local_file = platform_file;
- return Status();
-}
-
-bool PlatformMacOSX::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- return ARMGetSupportedArchitectureAtIndex(idx, arch);
-#else
- return x86GetSupportedArchitectureAtIndex(idx, arch);
-#endif
-}
-
-lldb_private::Status PlatformMacOSX::GetSharedModule(
- const lldb_private::ModuleSpec &module_spec, Process *process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
- Status error = GetSharedModuleWithLocalCache(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr);
-
- if (module_sp) {
- if (module_spec.GetArchitecture().GetCore() ==
- ArchSpec::eCore_x86_64_x86_64h) {
- ObjectFile *objfile = module_sp->GetObjectFile();
- if (objfile == NULL) {
- // We didn't find an x86_64h slice, fall back to a x86_64 slice
- ModuleSpec module_spec_x86_64(module_spec);
- module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx");
- lldb::ModuleSP x86_64_module_sp;
- lldb::ModuleSP old_x86_64_module_sp;
- bool did_create = false;
- Status x86_64_error = GetSharedModuleWithLocalCache(
- module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr,
- &old_x86_64_module_sp, &did_create);
- if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) {
- module_sp = x86_64_module_sp;
- if (old_module_sp_ptr)
- *old_module_sp_ptr = old_x86_64_module_sp;
- if (did_create_ptr)
- *did_create_ptr = did_create;
- return x86_64_error;
- }
- }
- }
- }
-
- if (!module_sp) {
- error = FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
- }
- return error;
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
deleted file mode 100644
index d08029a29f312..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//===-- PlatformMacOSX.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_PlatformMacOSX_h_
-#define liblldb_PlatformMacOSX_h_
-
-#include "PlatformDarwin.h"
-
-class PlatformMacOSX : public PlatformDarwin {
-public:
- PlatformMacOSX(bool is_host);
-
- ~PlatformMacOSX() override;
-
- //------------------------------------------------------------
- // Class functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic(bool is_host);
-
- static const char *GetDescriptionStatic(bool is_host);
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic(IsHost());
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- const char *GetDescription() override {
- return GetDescriptionStatic(IsHost());
- }
-
- lldb_private::Status
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Status
- GetFile(const lldb_private::FileSpec &source,
- const lldb_private::FileSpec &destination) override {
- return PlatformDarwin::GetFile(source, destination);
- }
-
- lldb_private::Status
- GetFileWithUUID(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- lldb_private::ConstString
- GetSDKDirectory(lldb_private::Target &target) override;
-
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::MacOSX);
- }
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformMacOSX);
-};
-
-#endif // liblldb_PlatformMacOSX_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
deleted file mode 100644
index fd804d0aaeed0..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-//===-- PlatformRemoteAppleBridge.cpp -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <string>
-#include <vector>
-
-#include "PlatformRemoteAppleBridge.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformRemoteAppleBridge::PlatformRemoteAppleBridge()
- : PlatformRemoteDarwinDevice () {}
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformRemoteAppleBridge::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(PlatformRemoteAppleBridge::GetPluginNameStatic(),
- PlatformRemoteAppleBridge::GetDescriptionStatic(),
- PlatformRemoteAppleBridge::CreateInstance);
- }
-}
-
-void PlatformRemoteAppleBridge::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformRemoteAppleBridge::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformRemoteAppleBridge::CreateInstance(bool force,
- const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformRemoteAppleBridge::%s(force=%s, arch={%s,%s})",
- __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::aarch64: {
- const llvm::Triple &triple = arch->GetTriple();
- llvm::Triple::VendorType vendor = triple.getVendor();
- switch (vendor) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-
-#endif
- default:
- break;
- }
- if (create) {
- switch (triple.getOS()) {
- // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
- break;
-
- default:
- create = false;
- break;
- }
- }
- } break;
- default:
- break;
- }
- }
-
- if (create) {
- if (log)
- log->Printf("PlatformRemoteAppleBridge::%s() creating platform",
- __FUNCTION__);
-
- return lldb::PlatformSP(new PlatformRemoteAppleBridge());
- }
-
- if (log)
- log->Printf("PlatformRemoteAppleBridge::%s() aborting creation of platform",
- __FUNCTION__);
-
- return lldb::PlatformSP();
-}
-
-lldb_private::ConstString PlatformRemoteAppleBridge::GetPluginNameStatic() {
- static ConstString g_name("remote-bridgeos");
- return g_name;
-}
-
-const char *PlatformRemoteAppleBridge::GetDescriptionStatic() {
- return "Remote BridgeOS platform plug-in.";
-}
-
-bool PlatformRemoteAppleBridge::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- ArchSpec system_arch(GetSystemArchitecture());
-
- const ArchSpec::Core system_core = system_arch.GetCore();
- switch (system_core) {
- default:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-bridgeos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-bridgeos");
- return true;
- default:
- break;
- }
- break;
- }
- arch.Clear();
- return false;
-}
-
-
-void PlatformRemoteAppleBridge::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
-{
- dirnames.clear();
- dirnames.push_back("BridgeOS DeviceSupport");
-}
-
-std::string PlatformRemoteAppleBridge::GetPlatformName ()
-{
- return "BridgeOS.platform";
-}
-
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
deleted file mode 100644
index 48f06eee3f019..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//===-- PlatformRemoteAppleBridge.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_PlatformRemoteAppleBridge_h_
-#define liblldb_PlatformRemoteAppleBridge_h_
-
-#include <string>
-
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/Support/FileSystem.h"
-
-#include "PlatformRemoteDarwinDevice.h"
-
-class PlatformRemoteAppleBridge : public PlatformRemoteDarwinDevice {
-public:
- PlatformRemoteAppleBridge();
-
- ~PlatformRemoteAppleBridge() override = default;
-
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
-protected:
-
- //------------------------------------------------------------
- // lldb_private::PlatformRemoteDarwinDevice functions
- //------------------------------------------------------------
-
- void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
-
- std::string GetPlatformName () override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleBridge);
-};
-
-#endif // liblldb_PlatformRemoteAppleBridge_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
deleted file mode 100644
index 593e888898c42..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-//===-- PlatformRemoteAppleTV.cpp -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <string>
-#include <vector>
-
-#include "PlatformRemoteAppleTV.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformRemoteAppleTV::PlatformRemoteAppleTV()
- : PlatformRemoteDarwinDevice () {}
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformRemoteAppleTV::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(PlatformRemoteAppleTV::GetPluginNameStatic(),
- PlatformRemoteAppleTV::GetDescriptionStatic(),
- PlatformRemoteAppleTV::CreateInstance);
- }
-}
-
-void PlatformRemoteAppleTV::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformRemoteAppleTV::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformRemoteAppleTV::CreateInstance(bool force,
- const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformRemoteAppleTV::%s(force=%s, arch={%s,%s})",
- __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb: {
- const llvm::Triple &triple = arch->GetTriple();
- llvm::Triple::VendorType vendor = triple.getVendor();
- switch (vendor) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-
-#endif
- default:
- break;
- }
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::TvOS: // This is the right triple value for Apple TV
- // debugging
- break;
-
- default:
- create = false;
- break;
- }
- }
- } break;
- default:
- break;
- }
- }
-
- if (create) {
- if (log)
- log->Printf("PlatformRemoteAppleTV::%s() creating platform",
- __FUNCTION__);
-
- return lldb::PlatformSP(new PlatformRemoteAppleTV());
- }
-
- if (log)
- log->Printf("PlatformRemoteAppleTV::%s() aborting creation of platform",
- __FUNCTION__);
-
- return lldb::PlatformSP();
-}
-
-lldb_private::ConstString PlatformRemoteAppleTV::GetPluginNameStatic() {
- static ConstString g_name("remote-tvos");
- return g_name;
-}
-
-const char *PlatformRemoteAppleTV::GetDescriptionStatic() {
- return "Remote Apple TV platform plug-in.";
-}
-
-bool PlatformRemoteAppleTV::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- ArchSpec system_arch(GetSystemArchitecture());
-
- const ArchSpec::Core system_core = system_arch.GetCore();
- switch (system_core) {
- default:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-tvos");
- return true;
- case 1:
- arch.SetTriple("armv7s-apple-tvos");
- return true;
- case 2:
- arch.SetTriple("armv7-apple-tvos");
- return true;
- case 3:
- arch.SetTriple("thumbv7s-apple-tvos");
- return true;
- case 4:
- arch.SetTriple("thumbv7-apple-tvos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-tvos");
- return true;
- case 1:
- arch.SetTriple("armv7s-apple-tvos");
- return true;
- case 2:
- arch.SetTriple("armv7-apple-tvos");
- return true;
- case 3:
- arch.SetTriple("thumbv7s-apple-tvos");
- return true;
- case 4:
- arch.SetTriple("thumbv7-apple-tvos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7s:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7s-apple-tvos");
- return true;
- case 1:
- arch.SetTriple("armv7-apple-tvos");
- return true;
- case 2:
- arch.SetTriple("thumbv7s-apple-tvos");
- return true;
- case 3:
- arch.SetTriple("thumbv7-apple-tvos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7-apple-tvos");
- return true;
- case 1:
- arch.SetTriple("thumbv7-apple-tvos");
- return true;
- default:
- break;
- }
- break;
- }
- arch.Clear();
- return false;
-}
-
-
-void PlatformRemoteAppleTV::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
-{
- dirnames.clear();
- dirnames.push_back("tvOS DeviceSupport");
-}
-
-std::string PlatformRemoteAppleTV::GetPlatformName ()
-{
- return "AppleTVOS.platform";
-}
-
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
deleted file mode 100644
index d8860a90a460b..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//===-- PlatformRemoteAppleTV.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_PlatformRemoteAppleTV_h_
-#define liblldb_PlatformRemoteAppleTV_h_
-
-#include <string>
-
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/Support/FileSystem.h"
-
-#include "PlatformRemoteDarwinDevice.h"
-
-class PlatformRemoteAppleTV : public PlatformRemoteDarwinDevice {
-public:
- PlatformRemoteAppleTV();
-
- ~PlatformRemoteAppleTV() override = default;
-
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
-protected:
-
- //------------------------------------------------------------
- // lldb_private::PlatformRemoteDarwinDevice functions
- //------------------------------------------------------------
-
- void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
-
- std::string GetPlatformName () override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleTV);
-};
-
-#endif // liblldb_PlatformRemoteAppleTV_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
deleted file mode 100644
index 59e6e19fbffcc..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-//===-- PlatformRemoteAppleWatch.cpp ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <string>
-#include <vector>
-
-#include "PlatformRemoteAppleWatch.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformRemoteAppleWatch::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(
- PlatformRemoteAppleWatch::GetPluginNameStatic(),
- PlatformRemoteAppleWatch::GetDescriptionStatic(),
- PlatformRemoteAppleWatch::CreateInstance);
- }
-}
-
-void PlatformRemoteAppleWatch::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformRemoteAppleWatch::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformRemoteAppleWatch::CreateInstance(bool force,
- const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformRemoteAppleWatch::%s(force=%s, arch={%s,%s})",
- __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb: {
- const llvm::Triple &triple = arch->GetTriple();
- llvm::Triple::VendorType vendor = triple.getVendor();
- switch (vendor) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-
-#endif
- default:
- break;
- }
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::WatchOS: // This is the right triple value for Apple
- // Watch debugging
- break;
-
- default:
- create = false;
- break;
- }
- }
- } break;
- default:
- break;
- }
- }
-
-#if defined(__APPLE__) && \
- (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
- // If lldb is running on a watch, this isn't a RemoteWatch environment; it's
- // a local system environment.
- if (force == false) {
- create = false;
- }
-#endif
-
- if (create) {
- if (log)
- log->Printf("PlatformRemoteAppleWatch::%s() creating platform",
- __FUNCTION__);
-
- return lldb::PlatformSP(new PlatformRemoteAppleWatch());
- }
-
- if (log)
- log->Printf("PlatformRemoteAppleWatch::%s() aborting creation of platform",
- __FUNCTION__);
-
- return lldb::PlatformSP();
-}
-
-lldb_private::ConstString PlatformRemoteAppleWatch::GetPluginNameStatic() {
- static ConstString g_name("remote-watchos");
- return g_name;
-}
-
-const char *PlatformRemoteAppleWatch::GetDescriptionStatic() {
- return "Remote Apple Watch platform plug-in.";
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformRemoteAppleWatch::PlatformRemoteAppleWatch()
- : PlatformRemoteDarwinDevice() {}
-
-bool PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- ArchSpec system_arch(GetSystemArchitecture());
-
- const ArchSpec::Core system_core = system_arch.GetCore();
- switch (system_core) {
- default:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-watchos");
- return true;
- case 1:
- arch.SetTriple("armv7k-apple-watchos");
- return true;
- case 2:
- arch.SetTriple("armv7s-apple-watchos");
- return true;
- case 3:
- arch.SetTriple("armv7-apple-watchos");
- return true;
- case 4:
- arch.SetTriple("thumbv7k-apple-watchos");
- return true;
- case 5:
- arch.SetTriple("thumbv7-apple-watchos");
- return true;
- case 6:
- arch.SetTriple("thumbv7s-apple-watchos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- switch (idx) {
- case 0:
- arch.SetTriple("arm64-apple-watchos");
- return true;
- case 1:
- arch.SetTriple("armv7k-apple-watchos");
- return true;
- case 2:
- arch.SetTriple("armv7s-apple-watchos");
- return true;
- case 3:
- arch.SetTriple("armv7-apple-watchos");
- return true;
- case 4:
- arch.SetTriple("thumbv7k-apple-watchos");
- return true;
- case 5:
- arch.SetTriple("thumbv7-apple-watchos");
- return true;
- case 6:
- arch.SetTriple("thumbv7s-apple-watchos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7k:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7k-apple-watchos");
- return true;
- case 1:
- arch.SetTriple("armv7s-apple-watchos");
- return true;
- case 2:
- arch.SetTriple("armv7-apple-watchos");
- return true;
- case 3:
- arch.SetTriple("thumbv7k-apple-watchos");
- return true;
- case 4:
- arch.SetTriple("thumbv7-apple-watchos");
- return true;
- case 5:
- arch.SetTriple("thumbv7s-apple-watchos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7s:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7s-apple-watchos");
- return true;
- case 1:
- arch.SetTriple("armv7k-apple-watchos");
- return true;
- case 2:
- arch.SetTriple("armv7-apple-watchos");
- return true;
- case 3:
- arch.SetTriple("thumbv7k-apple-watchos");
- return true;
- case 4:
- arch.SetTriple("thumbv7-apple-watchos");
- return true;
- case 5:
- arch.SetTriple("thumbv7s-apple-watchos");
- return true;
- default:
- break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7:
- switch (idx) {
- case 0:
- arch.SetTriple("armv7-apple-watchos");
- return true;
- case 1:
- arch.SetTriple("armv7k-apple-watchos");
- return true;
- case 2:
- arch.SetTriple("thumbv7k-apple-watchos");
- return true;
- case 3:
- arch.SetTriple("thumbv7-apple-watchos");
- return true;
- default:
- break;
- }
- break;
- }
- arch.Clear();
- return false;
-}
-
-void PlatformRemoteAppleWatch::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
-{
- dirnames.clear();
- dirnames.push_back("watchOS DeviceSupport");
-}
-
-std::string PlatformRemoteAppleWatch::GetPlatformName ()
-{
- return "WatchOS.platform";
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
deleted file mode 100644
index ed1cbea62e92f..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===-- PlatformRemoteAppleWatch.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_PlatformRemoteAppleWatch_h_
-#define liblldb_PlatformRemoteAppleWatch_h_
-
-#include <string>
-#include <vector>
-
-#include "lldb/Utility/FileSpec.h"
-
-#include "PlatformRemoteDarwinDevice.h"
-
-#include "llvm/Support/FileSystem.h"
-
-class PlatformRemoteAppleWatch : public PlatformRemoteDarwinDevice {
-public:
- PlatformRemoteAppleWatch();
-
- ~PlatformRemoteAppleWatch() override = default;
-
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
-protected:
-
- //------------------------------------------------------------
- // lldb_private::PlatformRemoteDarwinDevice functions
- //------------------------------------------------------------
-
- void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
-
- std::string GetPlatformName () override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleWatch);
-};
-
-#endif // liblldb_PlatformRemoteAppleWatch_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
deleted file mode 100644
index 511bfc20376b6..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
+++ /dev/null
@@ -1,661 +0,0 @@
-//===-- PlatformRemoteDarwinDevice.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformRemoteDarwinDevice.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(
- const lldb_private::FileSpec &sdk_dir)
- : directory(sdk_dir), build(), user_cached(false) {
- llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
- llvm::StringRef build_str;
- std::tie(version, build_str) = ParseVersionBuildDir(dirname_str);
- build.SetString(build_str);
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformRemoteDarwinDevice::PlatformRemoteDarwinDevice()
- : PlatformDarwin(false), // This is a remote platform
- m_sdk_directory_infos(), m_device_support_directory(),
- m_device_support_directory_for_os_version(), m_build_update(),
- m_last_module_sdk_idx(UINT32_MAX),
- m_connected_module_sdk_idx(UINT32_MAX) {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() {}
-
-void PlatformRemoteDarwinDevice::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
- if (sdk_directory)
- strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString(" SDK Path: error: unable to locate SDK\n");
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
- sdk_dir_info.directory.GetPath().c_str());
- }
-}
-
-Status PlatformRemoteDarwinDevice::ResolveExecutable(
- const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Status error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(ms);
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one
- // ourselves
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
- if (resolved_module_spec.GetArchitecture().IsValid() ||
- resolved_module_spec.GetUUID().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't found
- // so ask the platform for the architectures that we should be using (in
- // the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetData());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- } else {
- error.SetErrorStringWithFormat(
- "'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-FileSystem::EnumerateDirectoryResult
-PlatformRemoteDarwinDevice::GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
- ((PlatformRemoteDarwinDevice::SDKDirectoryInfoCollection *)baton)
- ->push_back(PlatformRemoteDarwinDevice::SDKDirectoryInfo(FileSpec(path)));
- return FileSystem::eEnumerateDirectoryResultNext;
-}
-
-bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
- if (m_sdk_directory_infos.empty()) {
- // A --sysroot option was supplied - add it to our list of SDKs to check
- if (m_sdk_sysroot) {
- FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString());
- FileSystem::Instance().Resolve(sdk_sysroot_fspec);
- const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
- m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
- if (log) {
- log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded added "
- "--sysroot SDK directory %s",
- m_sdk_sysroot.GetCString());
- }
- return true;
- }
- const char *device_support_dir = GetDeviceSupportDirectory();
- if (log) {
- log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded Got "
- "DeviceSupport directory %s",
- device_support_dir);
- }
- if (device_support_dir) {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
-
- SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSystem::Instance().EnumerateDirectory(
- m_device_support_directory, find_directories, find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &builtin_sdk_directory_infos);
-
- // Only add SDK directories that have symbols in them, some SDKs only
- // contain developer disk images and no symbols, so they aren't useful to
- // us.
- FileSpec sdk_symbols_symlink_fspec;
- for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
- sdk_symbols_symlink_fspec = sdk_directory_info.directory;
- sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
- if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log) {
- log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
- "added builtin SDK directory %s",
- sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
-
- std::vector<std::string> device_support_dirnames;
- GetDeviceSupportDirectoryNames (device_support_dirnames);
-
- for (std::string &dirname : device_support_dirnames)
- {
- const uint32_t num_installed = m_sdk_directory_infos.size();
- std::string local_sdk_cache_str = "~/Library/Developer/Xcode/";
- local_sdk_cache_str += dirname;
- FileSpec local_sdk_cache(local_sdk_cache_str.c_str());
- FileSystem::Instance().Resolve(local_sdk_cache);
- if (FileSystem::Instance().Exists(local_sdk_cache)) {
- if (log) {
- log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
- "searching %s for additional SDKs",
- local_sdk_cache.GetPath().c_str());
- }
- char path[PATH_MAX];
- if (local_sdk_cache.GetPath(path, sizeof(path))) {
- FileSystem::Instance().EnumerateDirectory(
- path, find_directories, find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &m_sdk_directory_infos);
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
- m_sdk_directory_infos[i].user_cached = true;
- if (log) {
- log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
- "user SDK directory %s",
- m_sdk_directory_infos[i].directory.GetPath().c_str());
- }
- }
- }
- }
- }
-
- const char *addtional_platform_dirs = getenv("PLATFORM_SDK_DIRECTORY");
- if (addtional_platform_dirs) {
- SDKDirectoryInfoCollection env_var_sdk_directory_infos;
- FileSystem::Instance().EnumerateDirectory(
- addtional_platform_dirs, find_directories, find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &env_var_sdk_directory_infos);
- FileSpec sdk_symbols_symlink_fspec;
- for (const auto &sdk_directory_info : env_var_sdk_directory_infos) {
- sdk_symbols_symlink_fspec = sdk_directory_info.directory;
- sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
- if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log) {
- log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
- "added env var SDK directory %s",
- sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
- }
-
- }
- }
- return !m_sdk_directory_infos.empty();
-}
-
-const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
-PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
- uint32_t i;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // Check to see if the user specified a build string. If they did, then be
- // sure to match it.
- std::vector<bool> check_sdk_info(num_sdk_infos, true);
- ConstString build(m_sdk_build);
- if (build) {
- for (i = 0; i < num_sdk_infos; ++i)
- check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
- }
-
- // If we are connected we can find the version of the OS the platform us
- // running on and select the right SDK
- llvm::VersionTuple version = GetOSVersion();
- if (!version.empty()) {
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- // First try for an exact match of major, minor and update
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version == version)
- return &m_sdk_directory_infos[i];
- }
- }
- // First try for an exact match of major and minor
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version.getMajor() ==
- version.getMajor() &&
- m_sdk_directory_infos[i].version.getMinor() ==
- version.getMinor()) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // Lastly try to match of major version only..
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version.getMajor() ==
- version.getMajor()) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- }
- } else if (build) {
- // No version, just a build number, search for the first one that matches
- for (i = 0; i < num_sdk_infos; ++i)
- if (check_sdk_info[i])
- return &m_sdk_directory_infos[i];
- }
- }
- return NULL;
-}
-
-const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
-PlatformRemoteDarwinDevice::GetSDKDirectoryForLatestOSVersion() {
- const PlatformRemoteDarwinDevice::SDKDirectoryInfo *result = NULL;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- auto max = std::max_element(
- m_sdk_directory_infos.begin(), m_sdk_directory_infos.end(),
- [](const SDKDirectoryInfo &a, const SDKDirectoryInfo &b) {
- return a.version < b.version;
- });
- if (max != m_sdk_directory_infos.end())
- result = &*max;
- }
- return result;
-}
-
-const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectory() {
- std::string platform_dir = "/Platforms/" + GetPlatformName() + "/DeviceSupport";
- if (m_device_support_directory.empty()) {
- const char *device_support_dir = GetDeveloperDirectory();
- if (device_support_dir) {
- m_device_support_directory.assign(device_support_dir);
- m_device_support_directory.append(platform_dir.c_str());
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into m_device_support_directory
- // or it should have a valid path if the code gets here
- assert(m_device_support_directory.empty() == false);
- if (m_device_support_directory[0])
- return m_device_support_directory.c_str();
- return NULL;
-}
-
-const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectoryForOSVersion() {
- if (m_sdk_sysroot)
- return m_sdk_sysroot.GetCString();
-
- if (m_device_support_directory_for_os_version.empty()) {
- const PlatformRemoteDarwinDevice::SDKDirectoryInfo *sdk_dir_info =
- GetSDKDirectoryForCurrentOSVersion();
- if (sdk_dir_info == NULL)
- sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
- if (sdk_dir_info) {
- char path[PATH_MAX];
- if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
- m_device_support_directory_for_os_version = path;
- return m_device_support_directory_for_os_version.c_str();
- }
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory_for_os_version.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into
- // m_device_support_directory_for_os_version or it should have a valid path
- // if the code gets here
- assert(m_device_support_directory_for_os_version.empty() == false);
- if (m_device_support_directory_for_os_version[0])
- return m_device_support_directory_for_os_version.c_str();
- return NULL;
-}
-
-uint32_t PlatformRemoteDarwinDevice::FindFileInAllSDKs(const char *platform_file_path,
- FileSpecList &file_list) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (platform_file_path && platform_file_path[0] &&
- UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- lldb_private::FileSpec local_file;
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
- file_list.Append(local_file);
- }
- }
- }
- return file_list.GetSize();
-}
-
-bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (sdk_idx < m_sdk_directory_infos.size()) {
- std::string sdkroot_path =
- m_sdk_directory_infos[sdk_idx].directory.GetPath();
- local_file.Clear();
-
- if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
- // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
- // the
- // SDK root directory and the file path.
-
- const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
- for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
- local_file.SetFile(sdkroot_path, FileSpec::Style::native);
- if (paths_to_try[i][0] != '\0')
- local_file.AppendPathComponent(paths_to_try[i]);
- local_file.AppendPathComponent(platform_file_path);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file)) {
- if (log)
- log->Printf("Found a copy of %s in the SDK dir %s/%s",
- platform_file_path, sdkroot_path.c_str(),
- paths_to_try[i]);
- return true;
- }
- local_file.Clear();
- }
- }
- }
- return false;
-}
-
-Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- Status error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- char resolved_path[PATH_MAX];
-
- const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
- if (os_version_dir) {
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file)) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s",
- platform_file_path, os_version_dir);
- }
- return error;
- }
-
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file)) {
- if (log) {
- log->Printf(
- "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file)) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- }
- local_file = platform_file;
- if (FileSystem::Instance().Exists(local_file))
- return error;
-
- error.SetErrorStringWithFormat(
- "unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path, GetPluginName().GetCString());
- } else {
- error.SetErrorString("invalid platform file argument");
- }
- return error;
-}
-
-Status PlatformRemoteDarwinDevice::GetSharedModule(
- const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) {
- // For iOS, the SDK files are all cached locally on the host system. So first
- // we ask for the file in the cached SDK, then we attempt to get a shared
- // module for the right architecture with the right UUID.
- const FileSpec &platform_file = module_spec.GetFileSpec();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-
- Status error;
- char platform_file_path[PATH_MAX];
-
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- ModuleSpec platform_module_spec(module_spec);
-
- UpdateSDKDirectoryInfosIfNeeded();
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // If we are connected we migth be able to correctly deduce the SDK
- // directory using the OS build.
- const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
- if (connected_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[connected_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, connected_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- m_last_module_sdk_idx = connected_sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
-
- // Try the last SDK index if it is set as most files from an SDK will tend
- // to be valid in that same SDK.
- if (m_last_module_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[m_last_module_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- error.Clear();
- return error;
- }
- }
- }
-
- // First try for an exact match of major, minor and update: If a particalar
- // SDK version was specified via --version or --build, look for a match on
- // disk.
- const SDKDirectoryInfo *current_sdk_info =
- GetSDKDirectoryForCurrentOSVersion();
- const uint32_t current_sdk_idx =
- GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
- if (current_sdk_idx < num_sdk_infos &&
- current_sdk_idx != m_last_module_sdk_idx) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[current_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, current_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- m_last_module_sdk_idx = current_sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
-
- // Second try all SDKs that were found.
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- if (m_last_module_sdk_idx == sdk_idx) {
- // Skip the last module SDK index if we already searched it above
- continue;
- }
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx,
- platform_module_spec.GetFileSpec())) {
- // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
-
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- // Remember the index of the last SDK that we found a file in in case
- // the wrong SDK was selected.
- m_last_module_sdk_idx = sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
- }
- // Not the module we are looking for... Nothing to see here...
- module_sp.reset();
-
- // This may not be an SDK-related module. Try whether we can bring in the
- // thing to our local cache.
- error = GetSharedModuleWithLocalCache(module_spec, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- if (error.Success())
- return error;
-
- // See if the file is present in any of the module_search_paths_ptr
- // directories.
- if (!module_sp)
- error = PlatformDarwin::FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp,
- module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
-
- if (error.Success())
- return error;
-
- const bool always_create = false;
- error = ModuleList::GetSharedModule(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr, always_create);
-
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
-}
-
-uint32_t PlatformRemoteDarwinDevice::GetConnectedSDKIndex() {
- if (IsConnected()) {
- if (m_connected_module_sdk_idx == UINT32_MAX) {
- std::string build;
- if (GetRemoteOSBuildString(build)) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
- build.c_str())) {
- m_connected_module_sdk_idx = i;
- }
- }
- }
- }
- } else {
- m_connected_module_sdk_idx = UINT32_MAX;
- }
- return m_connected_module_sdk_idx;
-}
-
-uint32_t PlatformRemoteDarwinDevice::GetSDKIndexBySDKDirectoryInfo(
- const SDKDirectoryInfo *sdk_info) {
- if (sdk_info == NULL) {
- return UINT32_MAX;
- }
-
- return sdk_info - &m_sdk_directory_infos[0];
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
deleted file mode 100644
index d32179d6c98e3..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===-- PlatformRemoteDarwinDevice.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_PlatformRemoteDarwinDevice_h_
-#define liblldb_PlatformRemoteDarwinDevice_h_
-
-#include <string>
-
-#include "PlatformDarwin.h"
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/Support/FileSystem.h"
-
-class PlatformRemoteDarwinDevice : public PlatformDarwin {
-public:
- PlatformRemoteDarwinDevice();
-
- ~PlatformRemoteDarwinDevice() override;
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Status ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- virtual lldb_private::Status
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::iPhoneOS);
- }
-
-protected:
- struct SDKDirectoryInfo {
- SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
- lldb_private::FileSpec directory;
- lldb_private::ConstString build;
- llvm::VersionTuple version;
- bool user_cached;
- };
-
- typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
-
- std::mutex m_sdk_dir_mutex;
- SDKDirectoryInfoCollection m_sdk_directory_infos;
- std::string m_device_support_directory;
- std::string m_device_support_directory_for_os_version;
- std::string m_build_update;
- uint32_t m_last_module_sdk_idx;
- uint32_t m_connected_module_sdk_idx;
-
- bool UpdateSDKDirectoryInfosIfNeeded();
-
- const char *GetDeviceSupportDirectory();
-
- const char *GetDeviceSupportDirectoryForOSVersion();
-
- const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
-
- const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
-
- static lldb_private::FileSystem::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback(void *baton,
- llvm::sys::fs::file_type ft,
- llvm::StringRef path);
-
- uint32_t FindFileInAllSDKs(const char *platform_file_path,
- lldb_private::FileSpecList &file_list);
-
- bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
- lldb_private::FileSpec &local_file);
-
- uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
- lldb_private::FileSpecList &file_list);
-
- uint32_t GetConnectedSDKIndex();
-
- // Get index of SDK in SDKDirectoryInfoCollection by its pointer and return
- // UINT32_MAX if that SDK not found.
- uint32_t GetSDKIndexBySDKDirectoryInfo(const SDKDirectoryInfo *sdk_info);
-
-
- virtual void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) = 0;
-
- virtual std::string GetPlatformName () = 0;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformRemoteDarwinDevice);
-};
-
-#endif // liblldb_PlatformRemoteDarwinDevice_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
deleted file mode 100644
index b69d7ea36abf3..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-//===-- PlatformRemoteiOS.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformRemoteiOS.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformRemoteiOS::Initialize() {
- PlatformDarwin::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(PlatformRemoteiOS::GetPluginNameStatic(),
- PlatformRemoteiOS::GetDescriptionStatic(),
- PlatformRemoteiOS::CreateInstance);
- }
-}
-
-void PlatformRemoteiOS::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformRemoteiOS::CreateInstance);
- }
- }
-
- PlatformDarwin::Terminate();
-}
-
-PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformRemoteiOS::%s(force=%s, arch={%s,%s})", __FUNCTION__,
- force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb: {
- const llvm::Triple &triple = arch->GetTriple();
- llvm::Triple::VendorType vendor = triple.getVendor();
- switch (vendor) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-
-#endif
- default:
- break;
- }
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
- // historical reasons
- case llvm::Triple::IOS: // This is the right triple value for iOS
- // debugging
- break;
-
- default:
- create = false;
- break;
- }
- }
- } break;
- default:
- break;
- }
- }
-
- if (create) {
- if (log)
- log->Printf("PlatformRemoteiOS::%s() creating platform", __FUNCTION__);
-
- return lldb::PlatformSP(new PlatformRemoteiOS());
- }
-
- if (log)
- log->Printf("PlatformRemoteiOS::%s() aborting creation of platform",
- __FUNCTION__);
-
- return lldb::PlatformSP();
-}
-
-lldb_private::ConstString PlatformRemoteiOS::GetPluginNameStatic() {
- static ConstString g_name("remote-ios");
- return g_name;
-}
-
-const char *PlatformRemoteiOS::GetDescriptionStatic() {
- return "Remote iOS platform plug-in.";
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformRemoteiOS::PlatformRemoteiOS()
- : PlatformRemoteDarwinDevice() {}
-
-bool PlatformRemoteiOS::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- return ARMGetSupportedArchitectureAtIndex(idx, arch);
-}
-
-
-void PlatformRemoteiOS::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
-{
- dirnames.clear();
- dirnames.push_back("iOS DeviceSupport");
-}
-
-std::string PlatformRemoteiOS::GetPlatformName ()
-{
- return "iPhoneOS.platform";
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
deleted file mode 100644
index 7e45dc3c2889b..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===-- PlatformRemoteiOS.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_PlatformRemoteiOS_h_
-#define liblldb_PlatformRemoteiOS_h_
-
-#include <string>
-
-#include "PlatformRemoteDarwinDevice.h"
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/Support/FileSystem.h"
-
-class PlatformRemoteiOS : public PlatformRemoteDarwinDevice {
-public:
- PlatformRemoteiOS();
-
- ~PlatformRemoteiOS() override = default;
-
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
-protected:
-
- //------------------------------------------------------------
- // lldb_private::PlatformRemoteDarwinDevice functions
- //------------------------------------------------------------
-
- void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
-
- std::string GetPlatformName () override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformRemoteiOS);
-};
-
-#endif // liblldb_PlatformRemoteiOS_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
deleted file mode 100644
index b1d5960bb6823..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-//===-- PlatformiOSSimulator.cpp -----------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformiOSSimulator.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "llvm/Support/FileSystem.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//------------------------------------------------------------------
-// Static Variables
-//------------------------------------------------------------------
-static uint32_t g_initialize_count = 0;
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-void PlatformiOSSimulator::Initialize() {
- PlatformAppleSimulator::Initialize();
-
- if (g_initialize_count++ == 0) {
- PluginManager::RegisterPlugin(PlatformiOSSimulator::GetPluginNameStatic(),
- PlatformiOSSimulator::GetDescriptionStatic(),
- PlatformiOSSimulator::CreateInstance);
- }
-}
-
-void PlatformiOSSimulator::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformiOSSimulator::CreateInstance);
- }
- }
-
- PlatformAppleSimulator::Terminate();
-}
-
-PlatformSP PlatformiOSSimulator::CreateInstance(bool force,
- const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log) {
- const char *arch_name;
- if (arch && arch->GetArchitectureName())
- arch_name = arch->GetArchitectureName();
- else
- arch_name = "<null>";
-
- const char *triple_cstr =
- arch ? arch->GetTriple().getTriple().c_str() : "<null>";
-
- log->Printf("PlatformiOSSimulator::%s(force=%s, arch={%s,%s})",
- __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- switch (arch->GetMachine()) {
- case llvm::Triple::x86_64:
- case llvm::Triple::x86: {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::Apple:
- create = true;
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the vendor if the host is Apple and it
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-#endif
- default:
- break;
- }
-
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
- // historical reasons
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS: // IOS is not used for simulator triples, but
- // accept it just in case
- break;
-
-#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and it
- // "unknown" wasn't specified (it was just returned because it was NOT
- // specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
-#endif
- default:
- create = false;
- break;
- }
- }
- } break;
- default:
- break;
- }
- }
- if (create) {
- if (log)
- log->Printf("PlatformiOSSimulator::%s() creating platform", __FUNCTION__);
-
- return PlatformSP(new PlatformiOSSimulator());
- }
-
- if (log)
- log->Printf("PlatformiOSSimulator::%s() aborting creation of platform",
- __FUNCTION__);
-
- return PlatformSP();
-}
-
-lldb_private::ConstString PlatformiOSSimulator::GetPluginNameStatic() {
- static ConstString g_name("ios-simulator");
- return g_name;
-}
-
-const char *PlatformiOSSimulator::GetDescriptionStatic() {
- return "iOS simulator platform plug-in.";
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformiOSSimulator::PlatformiOSSimulator()
- : PlatformAppleSimulator(), m_sdk_dir_mutex(), m_sdk_directory(),
- m_build_update() {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformiOSSimulator::~PlatformiOSSimulator() {}
-
-void PlatformiOSSimulator::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- const char *sdk_directory = GetSDKDirectoryAsCString();
- if (sdk_directory)
- strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString(" SDK Path: error: unable to locate SDK\n");
- PlatformAppleSimulator::GetStatus(strm);
-}
-
-Status PlatformiOSSimulator::ResolveExecutable(
- const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Status error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(module_spec);
-
- // If we have "ls" as the exe_file, resolve the executable loation based on
- // the current path variables
- // TODO: resolve bare executables in the Platform SDK
- // if (!resolved_exe_file.Exists())
- // resolved_exe_file.ResolveExecutableLocation ();
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one
- // ourselves
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
- if (resolved_module_spec.GetArchitecture().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't found
- // so ask the platform for the architectures that we should be using (in
- // the correct order) and see if we can find a match that way
- StreamString arch_names;
- ArchSpec platform_arch;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- // Only match x86 with x86 and x86_64 with x86_64...
- if (!module_spec.GetArchitecture().IsValid() ||
- module_spec.GetArchitecture().GetCore() ==
- resolved_module_spec.GetArchitecture().GetCore()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(platform_arch.GetArchitectureName());
- }
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetString().str().c_str());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- } else {
- error.SetErrorStringWithFormat("'%s' does not exist",
- module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-static FileSystem::EnumerateDirectoryResult
-EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft,
- llvm::StringRef path) {
- if (ft == llvm::sys::fs::file_type::directory_file) {
- FileSpec file_spec(path);
- const char *filename = file_spec.GetFilename().GetCString();
- if (filename &&
- strncmp(filename, "iPhoneSimulator", strlen("iPhoneSimulator")) == 0) {
- ::snprintf((char *)baton, PATH_MAX, "%s", filename);
- return FileSystem::eEnumerateDirectoryResultQuit;
- }
- }
- return FileSystem::eEnumerateDirectoryResultNext;
-}
-
-const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() {
- std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
- if (m_sdk_directory.empty()) {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir) {
- char sdks_directory[PATH_MAX];
- char sdk_dirname[PATH_MAX];
- sdk_dirname[0] = '\0';
- snprintf(sdks_directory, sizeof(sdks_directory),
- "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs",
- developer_dir);
- FileSpec simulator_sdk_spec;
- bool find_directories = true;
- bool find_files = false;
- bool find_other = false;
- FileSystem::Instance().EnumerateDirectory(
- sdks_directory, find_directories, find_files, find_other,
- EnumerateDirectoryCallback, sdk_dirname);
-
- if (sdk_dirname[0]) {
- m_sdk_directory = sdks_directory;
- m_sdk_directory.append(1, '/');
- m_sdk_directory.append(sdk_dirname);
- return m_sdk_directory.c_str();
- }
- }
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_sdk_directory.assign(1, '\0');
- }
-
- // We should have put a single NULL character into m_sdk_directory or it
- // should have a valid path if the code gets here
- assert(m_sdk_directory.empty() == false);
- if (m_sdk_directory[0])
- return m_sdk_directory.c_str();
- return NULL;
-}
-
-Status PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- Status error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- char resolved_path[PATH_MAX];
-
- const char *sdk_dir = GetSDKDirectoryAsCString();
- if (sdk_dir) {
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
- platform_file_path);
-
- // First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file))
- return error;
-
- // Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, FileSpec::Style::native);
- FileSystem::Instance().Resolve(local_file);
- if (FileSystem::Instance().Exists(local_file))
- return error;
- }
- error.SetErrorStringWithFormat(
- "unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path, GetPluginName().GetCString());
- } else {
- error.SetErrorString("invalid platform file argument");
- }
- return error;
-}
-
-Status PlatformiOSSimulator::GetSharedModule(
- const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) {
- // For iOS, the SDK files are all cached locally on the host system. So first
- // we ask for the file in the cached SDK, then we attempt to get a shared
- // module for the right architecture with the right UUID.
- Status error;
- ModuleSpec platform_module_spec(module_spec);
- const FileSpec &platform_file = module_spec.GetFileSpec();
- error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
- platform_module_spec.GetFileSpec());
- if (error.Success()) {
- error = ResolveExecutable(platform_module_spec, module_sp,
- module_search_paths_ptr);
- } else {
- const bool always_create = false;
- error = ModuleList::GetSharedModule(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr, always_create);
- }
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
-}
-
-uint32_t
-PlatformiOSSimulator::FindProcesses(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) {
- ProcessInstanceInfoList all_osx_process_infos;
- // First we get all OSX processes
- const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
-
- // Now we filter them down to only the iOS triples
- for (uint32_t i = 0; i < n; ++i) {
- const ProcessInstanceInfo &proc_info =
- all_osx_process_infos.GetProcessInfoAtIndex(i);
- if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::IOS) {
- process_infos.Append(proc_info);
- }
- }
- return process_infos.GetSize();
-}
-
-bool PlatformiOSSimulator::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- static const ArchSpec platform_arch(
- HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
- static const ArchSpec platform_arch64(
- HostInfo::GetArchitecture(HostInfo::eArchKind64));
-
- if (idx == 0) {
- arch = platform_arch;
- if (arch.IsValid()) {
- arch.GetTriple().setOS(llvm::Triple::IOS);
- return true;
- }
- } else {
- if (platform_arch.IsExactMatch(platform_arch64)) {
- // This macosx platform supports both 32 and 64 bit.
- if (idx == 1) {
- // 32/64: return "x86_64-apple-macosx" for architecture 1
- arch = platform_arch64;
- return true;
- } else if (idx == 2 || idx == 3) {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- if (arch.IsValid()) {
- if (idx == 2)
- arch.GetTriple().setOS(llvm::Triple::IOS);
- // 32/64: return "i386-apple-ios" for architecture 2 32/64: return
- // "i386-apple-macosx" for architecture 3
- return true;
- }
- }
- } else if (idx == 1) {
- // This macosx platform supports only 32 bit, so return the *-apple-
- // macosx version
- arch = platform_arch;
- return true;
- }
- }
- return false;
-}
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
deleted file mode 100644
index 4ac43a4dde28d..0000000000000
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- PlatformiOSSimulator.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_PlatformiOSSimulator_h_
-#define liblldb_PlatformiOSSimulator_h_
-
-#include <mutex>
-#include <string>
-
-#include "PlatformAppleSimulator.h"
-
-class PlatformiOSSimulator : public PlatformAppleSimulator {
-public:
- PlatformiOSSimulator();
-
- ~PlatformiOSSimulator() override;
-
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetDescriptionStatic();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Status ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- virtual lldb_private::Status
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- uint32_t
- FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::iPhoneSimulator);
- }
-
-protected:
- std::mutex m_sdk_dir_mutex;
- std::string m_sdk_directory;
- std::string m_build_update;
-
- const char *GetSDKDirectoryAsCString();
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformiOSSimulator);
-};
-
-#endif // liblldb_PlatformiOSSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt b/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt
deleted file mode 100644
index 946ff0a64c26f..0000000000000
--- a/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-remove_module_flags()
-include_directories(.)
-
-add_lldb_library(lldbPluginPlatformMacOSXObjCXX
- PlatformiOSSimulatorCoreSimulatorSupport.mm
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- lldbUtility
- ${EXTRA_LIBS}
-
- LINK_COMPONENTS
- Object
- Support
- )
diff --git a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
deleted file mode 100644
index bec35aaaf33b6..0000000000000
--- a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
+++ /dev/null
@@ -1,221 +0,0 @@
-//===-- PlatformiOSSimulatorCoreSimulatorSupport.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_PlatformiOSSimulatorCoreSimulatorSupport_h_
-#define liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_
-
-#include <functional>
-#include <ostream>
-#include <string>
-#include <vector>
-#ifdef __APPLE__
-#include <objc/objc.h>
-#else
-typedef void *id;
-#endif
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Utility/Args.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Status.h"
-
-#include "llvm/ADT/Optional.h"
-
-// And now the actual magic
-namespace CoreSimulatorSupport {
-class Process {
-public:
- lldb::pid_t GetPID() { return m_pid; }
-
- explicit operator bool() { return m_pid != LLDB_INVALID_PROCESS_ID; }
-
- lldb_private::Status GetError() { return m_error; }
-
-private:
- Process(lldb::pid_t p);
-
- Process(lldb_private::Status error);
-
- Process(lldb::pid_t p, lldb_private::Status error);
-
- lldb::pid_t m_pid;
- lldb_private::Status m_error;
-
- friend class Device;
-};
-
-class ModelIdentifier {
-public:
- ModelIdentifier(const std::string &mi);
- ModelIdentifier();
-
- explicit operator bool() const { return !m_versions.empty(); }
-
- size_t GetNumVersions() const { return m_versions.size(); }
-
- unsigned int GetVersionAtIndex(size_t idx) const { return m_versions[idx]; }
-
- std::string GetFamily() const { return m_family.c_str(); }
-
-private:
- std::string m_family;
- std::vector<unsigned int> m_versions;
-};
-
-class DeviceType {
-public:
- enum class ProductFamilyID : int32_t {
- iPhone = 1,
- iPad = 2,
- appleTV = 3,
- appleWatch = 4
- };
-
- DeviceType();
-
- DeviceType(id d);
-
- explicit operator bool();
-
- std::string GetName();
-
- lldb_private::ConstString GetIdentifier();
-
- ModelIdentifier GetModelIdentifier();
-
- lldb_private::ConstString GetProductFamily();
-
- ProductFamilyID GetProductFamilyID();
-
-private:
- id m_dev;
- llvm::Optional<ModelIdentifier> m_model_identifier;
-};
-
-class OSVersion {
-public:
- OSVersion(const std::string &ver, const std::string &build);
-
- OSVersion();
-
- explicit operator bool() const { return !m_versions.empty(); }
-
- size_t GetNumVersions() const { return m_versions.size(); }
-
- unsigned int GetVersionAtIndex(size_t idx) const { return m_versions[idx]; }
-
- const char *GetBuild() const { return m_build.c_str(); }
-
-private:
- std::vector<unsigned int> m_versions;
- std::string m_build;
-};
-
-class DeviceRuntime {
-public:
- DeviceRuntime();
-
- DeviceRuntime(id d);
-
- explicit operator bool();
-
- OSVersion GetVersion();
-
- bool IsAvailable();
-
-private:
- id m_dev;
- llvm::Optional<OSVersion> m_os_version;
-};
-
-class Device {
-private:
- typedef unsigned long int NSUInteger;
-
-public:
- enum class State : NSUInteger {
- Creating,
- Shutdown,
- Booting,
- Booted,
- ShuttingDown
- };
-
- Device();
-
- Device(id d);
-
- explicit operator bool();
-
- std::string GetName() const;
-
- DeviceType GetDeviceType();
-
- DeviceRuntime GetDeviceRuntime();
-
- State GetState();
-
- bool Boot(lldb_private::Status &err);
-
- bool Shutdown(lldb_private::Status &err);
-
- std::string GetUDID() const;
-
- Process Spawn(lldb_private::ProcessLaunchInfo &launch_info);
-
-private:
- id m_dev;
- llvm::Optional<DeviceType> m_dev_type;
- llvm::Optional<DeviceRuntime> m_dev_runtime;
-
- friend class DeviceSet;
-};
-
-bool operator>(const OSVersion &lhs, const OSVersion &rhs);
-
-bool operator>(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
-
-bool operator<(const OSVersion &lhs, const OSVersion &rhs);
-
-bool operator<(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
-
-bool operator==(const OSVersion &lhs, const OSVersion &rhs);
-
-bool operator==(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
-
-bool operator!=(const OSVersion &lhs, const OSVersion &rhs);
-
-bool operator!=(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
-
-class DeviceSet {
-public:
- static DeviceSet GetAllDevices(const char *developer_dir);
-
- static DeviceSet GetAvailableDevices(const char *developer_dir);
-
- size_t GetNumDevices();
-
- Device GetDeviceAtIndex(size_t idx);
-
- void ForEach(std::function<bool(const Device &)> f);
-
- DeviceSet GetDevicesIf(std::function<bool(Device)> f);
-
- DeviceSet GetDevices(DeviceType::ProductFamilyID dev_id);
-
- Device GetFanciest(DeviceType::ProductFamilyID dev_id);
-
-private:
- DeviceSet(id arr) : m_dev(arr) {}
-
- id m_dev;
-};
-}
-
-#endif // liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_
diff --git a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
deleted file mode 100644
index a601e27dc8a11..0000000000000
--- a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ /dev/null
@@ -1,634 +0,0 @@
-//===-- PlatformiOSSimulatorCoreSimulatorSupport.cpp ---------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformiOSSimulatorCoreSimulatorSupport.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-// Project includes
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Target/FileAction.h"
-
-#include "llvm/ADT/StringRef.h"
-
-using namespace lldb_private;
-// CoreSimulator lives as part of Xcode, which means we can't really link
-// against it, so we dlopen()
-// it at runtime, and error out nicely if that fails
-@interface SimServiceContext {
-}
-+ (id)sharedServiceContextForDeveloperDir:(NSString *)dir
- error:(NSError **)error;
-@end
-// However, the drawback is that the compiler will not know about the selectors
-// we're trying to use
-// until runtime; to appease clang in this regard, define a fake protocol on
-// NSObject that exposes
-// the needed interface names for us
-@protocol LLDBCoreSimulatorSupport <NSObject>
-- (id)defaultDeviceSetWithError:(NSError **)error;
-- (NSArray *)devices;
-- (id)deviceType;
-- (NSString *)name;
-- (NSString *)identifier;
-- (NSString *)modelIdentifier;
-- (NSString *)productFamily;
-- (int32_t)productFamilyID;
-- (id)runtime;
-- (BOOL)available;
-- (NSString *)versionString;
-- (NSString *)buildVersionString;
-- (BOOL)bootWithOptions:(NSDictionary *)options error:(NSError **)error;
-- (NSUInteger)state;
-- (BOOL)shutdownWithError:(NSError **)error;
-- (NSUUID *)UDID;
-- (pid_t)spawnWithPath:(NSString *)path
- options:(NSDictionary *)options
- terminationHandler:(void (^)(int status))terminationHandler
- error:(NSError **)error;
-@end
-
-CoreSimulatorSupport::Process::Process(lldb::pid_t p) : m_pid(p), m_error() {}
-
-CoreSimulatorSupport::Process::Process(Status error)
- : m_pid(LLDB_INVALID_PROCESS_ID), m_error(error) {}
-
-CoreSimulatorSupport::Process::Process(lldb::pid_t p, Status error)
- : m_pid(p), m_error(error) {}
-
-CoreSimulatorSupport::DeviceType::DeviceType()
- : m_dev(nil), m_model_identifier() {}
-
-CoreSimulatorSupport::DeviceType::DeviceType(id d)
- : m_dev(d), m_model_identifier() {}
-
-CoreSimulatorSupport::DeviceType::operator bool() { return m_dev != nil; }
-
-ConstString CoreSimulatorSupport::DeviceType::GetIdentifier() {
- return ConstString([[m_dev identifier] UTF8String]);
-}
-
-ConstString CoreSimulatorSupport::DeviceType::GetProductFamily() {
- return ConstString([[m_dev productFamily] UTF8String]);
-}
-
-CoreSimulatorSupport::DeviceType::ProductFamilyID
-CoreSimulatorSupport::DeviceType::GetProductFamilyID() {
- return ProductFamilyID([m_dev productFamilyID]);
-}
-
-CoreSimulatorSupport::DeviceRuntime::DeviceRuntime()
- : m_dev(nil), m_os_version() {}
-
-CoreSimulatorSupport::DeviceRuntime::DeviceRuntime(id d)
- : m_dev(d), m_os_version() {}
-
-CoreSimulatorSupport::DeviceRuntime::operator bool() { return m_dev != nil; }
-
-bool CoreSimulatorSupport::DeviceRuntime::IsAvailable() {
- return [m_dev available];
-}
-
-CoreSimulatorSupport::Device::Device()
- : m_dev(nil), m_dev_type(), m_dev_runtime() {}
-
-CoreSimulatorSupport::Device::Device(id d)
- : m_dev(d), m_dev_type(), m_dev_runtime() {}
-
-CoreSimulatorSupport::Device::operator bool() { return m_dev != nil; }
-
-CoreSimulatorSupport::Device::State CoreSimulatorSupport::Device::GetState() {
- return (State)([m_dev state]);
-}
-
-CoreSimulatorSupport::ModelIdentifier::ModelIdentifier(const std::string &mi)
- : m_family(), m_versions() {
- bool any = false;
- bool first_digit = false;
- unsigned int val = 0;
-
- for (char c : mi) {
- any = true;
- if (::isdigit(c)) {
- if (!first_digit)
- first_digit = true;
- val = 10 * val + (c - '0');
- } else if (c == ',') {
- if (first_digit) {
- m_versions.push_back(val);
- val = 0;
- } else
- m_family.push_back(c);
- } else {
- if (first_digit) {
- m_family.clear();
- m_versions.clear();
- return;
- } else {
- m_family.push_back(c);
- }
- }
- }
-
- if (first_digit)
- m_versions.push_back(val);
-}
-
-CoreSimulatorSupport::ModelIdentifier::ModelIdentifier()
- : ModelIdentifier("") {}
-
-CoreSimulatorSupport::OSVersion::OSVersion(const std::string &ver,
- const std::string &build)
- : m_versions(), m_build(build) {
- bool any = false;
- unsigned int val = 0;
- for (char c : ver) {
- if (c == '.') {
- m_versions.push_back(val);
- val = 0;
- } else if (::isdigit(c)) {
- val = 10 * val + (c - '0');
- any = true;
- } else {
- m_versions.clear();
- return;
- }
- }
- if (any)
- m_versions.push_back(val);
-}
-
-CoreSimulatorSupport::OSVersion::OSVersion() : OSVersion("", "") {}
-
-CoreSimulatorSupport::ModelIdentifier
-CoreSimulatorSupport::DeviceType::GetModelIdentifier() {
- if (!m_model_identifier.hasValue()) {
- auto utf8_model_id = [[m_dev modelIdentifier] UTF8String];
- if (utf8_model_id && *utf8_model_id)
- m_model_identifier = ModelIdentifier(utf8_model_id);
- }
-
- if (m_model_identifier.hasValue())
- return m_model_identifier.getValue();
- else
- return ModelIdentifier();
-}
-
-CoreSimulatorSupport::OSVersion
-CoreSimulatorSupport::DeviceRuntime::GetVersion() {
- if (!m_os_version.hasValue()) {
- auto utf8_ver_string = [[m_dev versionString] UTF8String];
- auto utf8_build_ver = [[m_dev buildVersionString] UTF8String];
- if (utf8_ver_string && *utf8_ver_string && utf8_build_ver &&
- *utf8_build_ver) {
- m_os_version = OSVersion(utf8_ver_string, utf8_build_ver);
- }
- }
-
- if (m_os_version.hasValue())
- return m_os_version.getValue();
- return OSVersion();
-}
-
-std::string CoreSimulatorSupport::DeviceType::GetName() {
- auto utf8_name = [[m_dev name] UTF8String];
- if (utf8_name)
- return std::string(utf8_name);
- return "";
-}
-
-std::string CoreSimulatorSupport::Device::GetName() const {
- auto utf8_name = [[m_dev name] UTF8String];
- if (utf8_name)
- return std::string(utf8_name);
- return "";
-}
-
-std::string CoreSimulatorSupport::Device::GetUDID() const {
- auto utf8_udid = [[[m_dev UDID] UUIDString] UTF8String];
- if (utf8_udid)
- return std::string(utf8_udid);
- else
- return std::string();
-}
-
-CoreSimulatorSupport::DeviceType CoreSimulatorSupport::Device::GetDeviceType() {
- if (!m_dev_type.hasValue())
- m_dev_type = DeviceType([m_dev deviceType]);
-
- return m_dev_type.getValue();
-}
-
-CoreSimulatorSupport::DeviceRuntime
-CoreSimulatorSupport::Device::GetDeviceRuntime() {
- if (!m_dev_runtime.hasValue())
- m_dev_runtime = DeviceRuntime([m_dev runtime]);
-
- return m_dev_runtime.getValue();
-}
-
-bool CoreSimulatorSupport::
-operator>(const CoreSimulatorSupport::OSVersion &lhs,
- const CoreSimulatorSupport::OSVersion &rhs) {
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l > r)
- return true;
- }
- return false;
-}
-
-bool CoreSimulatorSupport::
-operator>(const CoreSimulatorSupport::ModelIdentifier &lhs,
- const CoreSimulatorSupport::ModelIdentifier &rhs) {
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l > r)
- return true;
- }
- return false;
-}
-
-bool CoreSimulatorSupport::
-operator<(const CoreSimulatorSupport::OSVersion &lhs,
- const CoreSimulatorSupport::OSVersion &rhs) {
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l < r)
- return true;
- }
- return false;
-}
-
-bool CoreSimulatorSupport::
-operator<(const CoreSimulatorSupport::ModelIdentifier &lhs,
- const CoreSimulatorSupport::ModelIdentifier &rhs) {
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
-
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l < r)
- return true;
- }
- return false;
-}
-
-bool CoreSimulatorSupport::
-operator==(const CoreSimulatorSupport::OSVersion &lhs,
- const CoreSimulatorSupport::OSVersion &rhs) {
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return false;
- }
- return true;
-}
-
-bool CoreSimulatorSupport::
-operator==(const CoreSimulatorSupport::ModelIdentifier &lhs,
- const CoreSimulatorSupport::ModelIdentifier &rhs) {
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
-
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return false;
- }
- return true;
-}
-
-bool CoreSimulatorSupport::
-operator!=(const CoreSimulatorSupport::OSVersion &lhs,
- const CoreSimulatorSupport::OSVersion &rhs) {
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return true;
- }
- return false;
-}
-
-bool CoreSimulatorSupport::
-operator!=(const CoreSimulatorSupport::ModelIdentifier &lhs,
- const CoreSimulatorSupport::ModelIdentifier &rhs) {
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
-
- for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return true;
- }
- return false;
-}
-
-bool CoreSimulatorSupport::Device::Boot(Status &err) {
- if (m_dev == nil) {
- err.SetErrorString("no valid simulator instance");
- return false;
- }
-
-#define kSimDeviceBootPersist \
- @"persist" /* An NSNumber (boolean) indicating whether or not the session \
- should outlive the calling process (default false) */
-
- NSDictionary *options = @{
- kSimDeviceBootPersist : @NO,
- };
-
-#undef kSimDeviceBootPersist
-
- NSError *nserror;
- if ([m_dev bootWithOptions:options error:&nserror]) {
- err.Clear();
- return true;
- } else {
- err.SetErrorString([[nserror description] UTF8String]);
- return false;
- }
-}
-
-bool CoreSimulatorSupport::Device::Shutdown(Status &err) {
- NSError *nserror;
- if ([m_dev shutdownWithError:&nserror]) {
- err.Clear();
- return true;
- } else {
- err.SetErrorString([[nserror description] UTF8String]);
- return false;
- }
-}
-
-static Status HandleFileAction(ProcessLaunchInfo &launch_info,
- NSMutableDictionary *options, NSString *key,
- const int fd, File &file) {
- Status error;
- const FileAction *file_action = launch_info.GetFileActionForFD(fd);
- if (file_action) {
- switch (file_action->GetAction()) {
- case FileAction::eFileActionNone:
- break;
-
- case FileAction::eFileActionClose:
- error.SetErrorStringWithFormat("close file action for %i not supported",
- fd);
- break;
-
- case FileAction::eFileActionDuplicate:
- error.SetErrorStringWithFormat(
- "duplication file action for %i not supported", fd);
- break;
-
- case FileAction::eFileActionOpen: {
- FileSpec file_spec = file_action->GetFileSpec();
- if (file_spec) {
- const int master_fd = launch_info.GetPTY().GetMasterFileDescriptor();
- if (master_fd != PseudoTerminal::invalid_fd) {
- // Check in case our file action open wants to open the slave
- const char *slave_path = launch_info.GetPTY().GetSlaveName(NULL, 0);
- if (slave_path) {
- FileSpec slave_spec(slave_path);
- if (file_spec == slave_spec) {
- int slave_fd = launch_info.GetPTY().GetSlaveFileDescriptor();
- if (slave_fd == PseudoTerminal::invalid_fd)
- slave_fd = launch_info.GetPTY().OpenSlave(O_RDWR, nullptr, 0);
- if (slave_fd == PseudoTerminal::invalid_fd) {
- error.SetErrorStringWithFormat("unable to open slave pty '%s'",
- slave_path);
- return error; // Failure
- }
- [options setValue:[NSNumber numberWithInteger:slave_fd]
- forKey:key];
- return error; // Success
- }
- }
- }
- Status posix_error;
- int created_fd =
- open(file_spec.GetPath().c_str(), file_action->GetActionArgument(),
- S_IRUSR | S_IWUSR);
- if (created_fd >= 0) {
- file.SetDescriptor(created_fd, true);
- [options setValue:[NSNumber numberWithInteger:created_fd] forKey:key];
- return error; // Success
- } else {
- posix_error.SetErrorToErrno();
- error.SetErrorStringWithFormat("unable to open file '%s': %s",
- file_spec.GetPath().c_str(),
- posix_error.AsCString());
- }
- }
- } break;
- }
- }
- return error; // Success, no file action, nothing to do
-}
-
-CoreSimulatorSupport::Process
-CoreSimulatorSupport::Device::Spawn(ProcessLaunchInfo &launch_info) {
-#define kSimDeviceSpawnEnvironment \
- @"environment" /* An NSDictionary (NSStrings -> NSStrings) of environment \
- key/values */
-#define kSimDeviceSpawnStdin @"stdin" /* An NSNumber corresponding to a fd */
-#define kSimDeviceSpawnStdout @"stdout" /* An NSNumber corresponding to a fd \
- */
-#define kSimDeviceSpawnStderr @"stderr" /* An NSNumber corresponding to a fd \
- */
-#define kSimDeviceSpawnArguments \
- @"arguments" /* An NSArray of strings to use as the argv array. If not \
- provided, path will be argv[0] */
-#define kSimDeviceSpawnWaitForDebugger \
- @"wait_for_debugger" /* An NSNumber (bool) */
-
- NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
-
- if (launch_info.GetFlags().Test(lldb::eLaunchFlagDebug))
- [options setObject:@YES forKey:kSimDeviceSpawnWaitForDebugger];
-
- if (launch_info.GetArguments().GetArgumentCount()) {
- const Args &args(launch_info.GetArguments());
- NSMutableArray *args_array = [[NSMutableArray alloc] init];
- for (size_t idx = 0; idx < args.GetArgumentCount(); idx++)
- [args_array
- addObject:[NSString
- stringWithUTF8String:args.GetArgumentAtIndex(idx)]];
-
- [options setObject:args_array forKey:kSimDeviceSpawnArguments];
- }
-
- NSMutableDictionary *env_dict = [[NSMutableDictionary alloc] init];
-
- for (const auto &KV : launch_info.GetEnvironment()) {
- NSString *key_ns = [NSString stringWithUTF8String:KV.first().str().c_str()];
- NSString *value_ns = [NSString stringWithUTF8String:KV.second.c_str()];
-
- [env_dict setValue:value_ns forKey:key_ns];
- }
-
- [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment];
-
- Status error;
- File stdin_file;
- File stdout_file;
- File stderr_file;
- error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdin,
- STDIN_FILENO, stdin_file);
-
- if (error.Fail())
- return CoreSimulatorSupport::Process(error);
-
- error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdout,
- STDOUT_FILENO, stdout_file);
-
- if (error.Fail())
- return CoreSimulatorSupport::Process(error);
-
- error = HandleFileAction(launch_info, options, kSimDeviceSpawnStderr,
- STDERR_FILENO, stderr_file);
-
- if (error.Fail())
- return CoreSimulatorSupport::Process(error);
-
-#undef kSimDeviceSpawnEnvironment
-#undef kSimDeviceSpawnStdin
-#undef kSimDeviceSpawnStdout
-#undef kSimDeviceSpawnStderr
-#undef kSimDeviceSpawnWaitForDebugger
-#undef kSimDeviceSpawnArguments
-
- NSError *nserror;
-
- pid_t pid = [m_dev
- spawnWithPath:[NSString stringWithUTF8String:launch_info
- .GetExecutableFile()
- .GetPath()
- .c_str()]
- options:options
- terminationHandler:nil
- error:&nserror];
-
- if (pid < 0) {
- const char *nserror_string = [[nserror description] UTF8String];
- error.SetErrorString(nserror_string ? nserror_string : "unable to launch");
- }
-
- return CoreSimulatorSupport::Process(pid, error);
-}
-
-CoreSimulatorSupport::DeviceSet
-CoreSimulatorSupport::DeviceSet::GetAllDevices(const char *developer_dir) {
- if (!developer_dir || !developer_dir[0])
- return DeviceSet([NSArray new]);
-
- Class SimServiceContextClass = NSClassFromString(@"SimServiceContext");
- NSString *dev_dir = @(developer_dir);
- NSError *error = nil;
-
- id serviceContext =
- [SimServiceContextClass sharedServiceContextForDeveloperDir:dev_dir
- error:&error];
- if (!serviceContext)
- return DeviceSet([NSArray new]);
-
- return DeviceSet([[serviceContext defaultDeviceSetWithError:&error] devices]);
-}
-
-CoreSimulatorSupport::DeviceSet
-CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
- const char *developer_dir) {
- return GetAllDevices(developer_dir).GetDevicesIf([](Device d) -> bool {
- return (d && d.GetDeviceType() && d.GetDeviceRuntime() &&
- d.GetDeviceRuntime().IsAvailable());
- });
-}
-
-size_t CoreSimulatorSupport::DeviceSet::GetNumDevices() {
- return [m_dev count];
-}
-
-CoreSimulatorSupport::Device
-CoreSimulatorSupport::DeviceSet::GetDeviceAtIndex(size_t idx) {
- if (idx < GetNumDevices())
- return Device([m_dev objectAtIndex:idx]);
- return Device();
-}
-
-CoreSimulatorSupport::DeviceSet CoreSimulatorSupport::DeviceSet::GetDevicesIf(
- std::function<bool(CoreSimulatorSupport::Device)> f) {
- NSMutableArray *array = [[NSMutableArray alloc] init];
- for (NSUInteger i = 0; i < GetNumDevices(); i++) {
- Device d(GetDeviceAtIndex(i));
- if (f(d))
- [array addObject:(id)d.m_dev];
- }
-
- return DeviceSet(array);
-}
-
-void CoreSimulatorSupport::DeviceSet::ForEach(
- std::function<bool(const Device &)> f) {
- const size_t n = GetNumDevices();
- for (NSUInteger i = 0; i < n; ++i) {
- if (!f(GetDeviceAtIndex(i)))
- break;
- }
-}
-
-CoreSimulatorSupport::DeviceSet CoreSimulatorSupport::DeviceSet::GetDevices(
- CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id) {
- NSMutableArray *array = [[NSMutableArray alloc] init];
- const size_t n = GetNumDevices();
- for (NSUInteger i = 0; i < n; ++i) {
- Device d(GetDeviceAtIndex(i));
- if (d && d.GetDeviceType() &&
- d.GetDeviceType().GetProductFamilyID() == dev_id)
- [array addObject:(id)d.m_dev];
- }
-
- return DeviceSet(array);
-}
-
-CoreSimulatorSupport::Device CoreSimulatorSupport::DeviceSet::GetFanciest(
- CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id) {
- Device dev;
-
- for (NSUInteger i = 0; i < GetNumDevices(); i++) {
- Device d(GetDeviceAtIndex(i));
- if (d && d.GetDeviceType() &&
- d.GetDeviceType().GetProductFamilyID() == dev_id) {
- if (!dev)
- dev = d;
- else {
- if ((d.GetDeviceType().GetModelIdentifier() >
- dev.GetDeviceType().GetModelIdentifier()) ||
- d.GetDeviceRuntime().GetVersion() >
- dev.GetDeviceRuntime().GetVersion())
- dev = d;
- }
- }
- }
-
- return dev;
-}
diff --git a/source/Plugins/Platform/NetBSD/CMakeLists.txt b/source/Plugins/Platform/NetBSD/CMakeLists.txt
deleted file mode 100644
index 5e63f10980672..0000000000000
--- a/source/Plugins/Platform/NetBSD/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-add_lldb_library(lldbPluginPlatformNetBSD PLUGIN
- PlatformNetBSD.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbTarget
- )
diff --git a/source/Plugins/Platform/OpenBSD/CMakeLists.txt b/source/Plugins/Platform/OpenBSD/CMakeLists.txt
deleted file mode 100644
index 8d49e7c4f196b..0000000000000
--- a/source/Plugins/Platform/OpenBSD/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-add_lldb_library(lldbPluginPlatformOpenBSD PLUGIN
- PlatformOpenBSD.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbTarget
- )
diff --git a/source/Plugins/Platform/POSIX/CMakeLists.txt b/source/Plugins/Platform/POSIX/CMakeLists.txt
deleted file mode 100644
index 749407d63d5c9..0000000000000
--- a/source/Plugins/Platform/POSIX/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginPlatformPOSIX PLUGIN
- PlatformPOSIX.cpp
-
- LINK_LIBS
- lldbCore
- lldbExpression
- lldbHost
- lldbInterpreter
- lldbTarget
- )
diff --git a/source/Plugins/Platform/Windows/CMakeLists.txt b/source/Plugins/Platform/Windows/CMakeLists.txt
deleted file mode 100644
index 49a197cdaff36..0000000000000
--- a/source/Plugins/Platform/Windows/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-add_lldb_library(lldbPluginPlatformWindows PLUGIN
- PlatformWindows.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbTarget
- )
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.cpp b/source/Plugins/Platform/Windows/PlatformWindows.cpp
deleted file mode 100644
index 685d49a73a777..0000000000000
--- a/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ /dev/null
@@ -1,593 +0,0 @@
-//===-- PlatformWindows.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PlatformWindows.h"
-
-#include <stdio.h>
-#if defined(_WIN32)
-#include "lldb/Host/windows/windows.h"
-#include <winsock2.h>
-#endif
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/BreakpointSite.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/Status.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-static uint32_t g_initialize_count = 0;
-
-namespace {
-class SupportedArchList {
-public:
- SupportedArchList() {
- AddArch(ArchSpec("i686-pc-windows"));
- AddArch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
- AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind32));
- AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind64));
- AddArch(ArchSpec("i386-pc-windows"));
- }
-
- size_t Count() const { return m_archs.size(); }
-
- const ArchSpec &operator[](int idx) { return m_archs[idx]; }
-
-private:
- void AddArch(const ArchSpec &spec) {
- auto iter = std::find_if(
- m_archs.begin(), m_archs.end(),
- [spec](const ArchSpec &rhs) { return spec.IsExactMatch(rhs); });
- if (iter != m_archs.end())
- return;
- if (spec.IsValid())
- m_archs.push_back(spec);
- }
-
- std::vector<ArchSpec> m_archs;
-};
-} // anonymous namespace
-
-PlatformSP PlatformWindows::CreateInstance(bool force,
- const lldb_private::ArchSpec *arch) {
- // The only time we create an instance is when we are creating a remote
- // windows platform
- const bool is_host = false;
-
- bool create = force;
- if (!create && arch && arch->IsValid()) {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor()) {
- case llvm::Triple::PC:
- create = true;
- break;
-
- case llvm::Triple::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
-
- default:
- break;
- }
-
- if (create) {
- switch (triple.getOS()) {
- case llvm::Triple::Win32:
- break;
-
- case llvm::Triple::UnknownOS:
- create = arch->TripleOSWasSpecified();
- break;
-
- default:
- create = false;
- break;
- }
- }
- }
- if (create)
- return PlatformSP(new PlatformWindows(is_host));
- return PlatformSP();
-}
-
-lldb_private::ConstString PlatformWindows::GetPluginNameStatic(bool is_host) {
- if (is_host) {
- static ConstString g_host_name(Platform::GetHostPlatformName());
- return g_host_name;
- } else {
- static ConstString g_remote_name("remote-windows");
- return g_remote_name;
- }
-}
-
-const char *PlatformWindows::GetPluginDescriptionStatic(bool is_host) {
- return is_host ? "Local Windows user platform plug-in."
- : "Remote Windows user platform plug-in.";
-}
-
-lldb_private::ConstString PlatformWindows::GetPluginName() {
- return GetPluginNameStatic(IsHost());
-}
-
-void PlatformWindows::Initialize() {
- Platform::Initialize();
-
- if (g_initialize_count++ == 0) {
-#if defined(_WIN32)
- WSADATA dummy;
- WSAStartup(MAKEWORD(2, 2), &dummy);
- // Force a host flag to true for the default platform object.
- PlatformSP default_platform_sp(new PlatformWindows(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform(default_platform_sp);
-#endif
- PluginManager::RegisterPlugin(
- PlatformWindows::GetPluginNameStatic(false),
- PlatformWindows::GetPluginDescriptionStatic(false),
- PlatformWindows::CreateInstance);
- }
-}
-
-void PlatformWindows::Terminate(void) {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
-#ifdef _WIN32
- WSACleanup();
-#endif
- PluginManager::UnregisterPlugin(PlatformWindows::CreateInstance);
- }
- }
-
- Platform::Terminate();
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformWindows::PlatformWindows(bool is_host) : Platform(is_host) {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformWindows::~PlatformWindows() = default;
-
-bool PlatformWindows::GetModuleSpec(const FileSpec &module_file_spec,
- const ArchSpec &arch,
- ModuleSpec &module_spec) {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
- module_spec);
-
- return Platform::GetModuleSpec(module_file_spec, arch, module_spec);
-}
-
-Status PlatformWindows::ResolveExecutable(
- const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Status error;
- // Nothing special to do here, just use the actual file and architecture
-
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec(ms);
-
- if (IsHost()) {
- // if we cant resolve the executable loation based on the current path
- // variables
- if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
- resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path,
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
- }
-
- if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
- FileSystem::Instance().ResolveExecutableLocation(
- resolved_module_spec.GetFileSpec());
-
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
- error.Clear();
- else {
- ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- error.SetErrorStringWithFormat("unable to find executable for '%s'",
- exe_path);
- }
- } else {
- if (m_remote_platform_sp) {
- error = GetCachedExecutable(resolved_module_spec, exe_module_sp, nullptr,
- *m_remote_platform_sp);
- } else {
- // We may connect to a process and use the provided executable (Don't use
- // local $PATH).
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
- error.Clear();
- else
- error.SetErrorStringWithFormat("the platform is not currently "
- "connected, and '%s' doesn't exist in "
- "the system root.",
- exe_path);
- }
- }
-
- if (error.Success()) {
- if (resolved_module_spec.GetArchitecture().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- nullptr, nullptr, nullptr);
-
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == nullptr) {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
- } else {
- // No valid architecture was specified, ask the platform for the
- // architectures that we should be using (in the correct order) and see
- // if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- nullptr, nullptr, nullptr);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (FileSystem::Instance().Readable(
- resolved_module_spec.GetFileSpec())) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetData());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- }
- }
-
- return error;
-}
-
-bool PlatformWindows::GetRemoteOSVersion() {
- if (m_remote_platform_sp) {
- m_os_version = m_remote_platform_sp->GetOSVersion();
- return !m_os_version.empty();
- }
- return false;
-}
-
-bool PlatformWindows::GetRemoteOSBuildString(std::string &s) {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSBuildString(s);
- s.clear();
- return false;
-}
-
-bool PlatformWindows::GetRemoteOSKernelDescription(std::string &s) {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
- s.clear();
- return false;
-}
-
-// Remote Platform subclasses need to override this function
-ArchSpec PlatformWindows::GetRemoteSystemArchitecture() {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteSystemArchitecture();
- return ArchSpec();
-}
-
-const char *PlatformWindows::GetHostname() {
- if (IsHost())
- return Platform::GetHostname();
-
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetHostname();
- return nullptr;
-}
-
-bool PlatformWindows::IsConnected() const {
- if (IsHost())
- return true;
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->IsConnected();
- return false;
-}
-
-Status PlatformWindows::ConnectRemote(Args &args) {
- Status error;
- if (IsHost()) {
- error.SetErrorStringWithFormat(
- "can't connect to the host platform '%s', always connected",
- GetPluginName().AsCString());
- } else {
- if (!m_remote_platform_sp)
- m_remote_platform_sp =
- Platform::Create(ConstString("remote-gdb-server"), error);
-
- if (m_remote_platform_sp) {
- if (error.Success()) {
- if (m_remote_platform_sp) {
- error = m_remote_platform_sp->ConnectRemote(args);
- } else {
- error.SetErrorString(
- "\"platform connect\" takes a single argument: <connect-url>");
- }
- }
- } else
- error.SetErrorString("failed to create a 'remote-gdb-server' platform");
-
- if (error.Fail())
- m_remote_platform_sp.reset();
- }
-
- return error;
-}
-
-Status PlatformWindows::DisconnectRemote() {
- Status error;
-
- if (IsHost()) {
- error.SetErrorStringWithFormat(
- "can't disconnect from the host platform '%s', always connected",
- GetPluginName().AsCString());
- } else {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->DisconnectRemote();
- else
- error.SetErrorString("the platform is not currently connected");
- }
- return error;
-}
-
-bool PlatformWindows::GetProcessInfo(lldb::pid_t pid,
- ProcessInstanceInfo &process_info) {
- bool success = false;
- if (IsHost()) {
- success = Platform::GetProcessInfo(pid, process_info);
- } else if (m_remote_platform_sp) {
- success = m_remote_platform_sp->GetProcessInfo(pid, process_info);
- }
- return success;
-}
-
-uint32_t
-PlatformWindows::FindProcesses(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) {
- uint32_t match_count = 0;
- if (IsHost()) {
- // Let the base class figure out the host details
- match_count = Platform::FindProcesses(match_info, process_infos);
- } else {
- // If we are remote, we can only return results if we are connected
- if (m_remote_platform_sp)
- match_count =
- m_remote_platform_sp->FindProcesses(match_info, process_infos);
- }
- return match_count;
-}
-
-Status PlatformWindows::LaunchProcess(ProcessLaunchInfo &launch_info) {
- Status error;
- if (IsHost()) {
- error = Platform::LaunchProcess(launch_info);
- } else {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->LaunchProcess(launch_info);
- else
- error.SetErrorString("the platform is not currently connected");
- }
- return error;
-}
-
-ProcessSP PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info,
- Debugger &debugger, Target *target,
- Status &error) {
- // Windows has special considerations that must be followed when launching or
- // attaching to a process. The key requirement is that when launching or
- // attaching to a process, you must do it from the same the thread that will
- // go into a permanent loop which will then receive debug events from the
- // process. In particular, this means we can't use any of LLDB's generic
- // mechanisms to do it for us, because it doesn't have the special knowledge
- // required for setting up the background thread or passing the right flags.
- //
- // Another problem is that that LLDB's standard model for debugging a process
- // is to first launch it, have it stop at the entry point, and then attach to
- // it. In Windows this doesn't quite work, you have to specify as an
- // argument to CreateProcess() that you're going to debug the process. So we
- // override DebugProcess here to handle this. Launch operations go directly
- // to the process plugin, and attach operations almost go directly to the
- // process plugin (but we hijack the events first). In essence, we
- // encapsulate all the logic of Launching and Attaching in the process
- // plugin, and PlatformWindows::DebugProcess is just a pass-through to get to
- // the process plugin.
-
- if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
- // This is a process attach. Don't need to launch anything.
- ProcessAttachInfo attach_info(launch_info);
- return Attach(attach_info, debugger, target, error);
- } else {
- ProcessSP process_sp = target->CreateProcess(
- launch_info.GetListener(), launch_info.GetProcessPluginName(), nullptr);
-
- // We need to launch and attach to the process.
- launch_info.GetFlags().Set(eLaunchFlagDebug);
- if (process_sp)
- error = process_sp->Launch(launch_info);
-
- return process_sp;
- }
-}
-
-lldb::ProcessSP PlatformWindows::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger, Target *target,
- Status &error) {
- error.Clear();
- lldb::ProcessSP process_sp;
- if (!IsHost()) {
- if (m_remote_platform_sp)
- process_sp =
- m_remote_platform_sp->Attach(attach_info, debugger, target, error);
- else
- error.SetErrorString("the platform is not currently connected");
- return process_sp;
- }
-
- if (target == nullptr) {
- TargetSP new_target_sp;
- FileSpec emptyFileSpec;
- ArchSpec emptyArchSpec;
-
- error = debugger.GetTargetList().CreateTarget(
- debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
- target = new_target_sp.get();
- }
-
- if (!target || error.Fail())
- return process_sp;
-
- debugger.GetTargetList().SetSelectedTarget(target);
-
- const char *plugin_name = attach_info.GetProcessPluginName();
- process_sp = target->CreateProcess(
- attach_info.GetListenerForProcess(debugger), plugin_name, nullptr);
-
- process_sp->HijackProcessEvents(attach_info.GetHijackListener());
- if (process_sp)
- error = process_sp->Attach(attach_info);
-
- return process_sp;
-}
-
-const char *PlatformWindows::GetUserName(uint32_t uid) {
- // Check the cache in Platform in case we have already looked this uid up
- const char *user_name = Platform::GetUserName(uid);
- if (user_name)
- return user_name;
-
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetUserName(uid);
- return nullptr;
-}
-
-const char *PlatformWindows::GetGroupName(uint32_t gid) {
- const char *group_name = Platform::GetGroupName(gid);
- if (group_name)
- return group_name;
-
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetGroupName(gid);
- return nullptr;
-}
-
-Status PlatformWindows::GetFileWithUUID(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- if (IsRemote()) {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
- local_file);
- }
-
- // Default to the local case
- local_file = platform_file;
- return Status();
-}
-
-Status PlatformWindows::GetSharedModule(
- const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) {
- Status error;
- module_sp.reset();
-
- if (IsRemote()) {
- // If we have a remote platform always, let it try and locate the shared
- // module first.
- if (m_remote_platform_sp) {
- error = m_remote_platform_sp->GetSharedModule(
- module_spec, process, module_sp, module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- }
- }
-
- if (!module_sp) {
- // Fall back to the local platform and find the file locally
- error = Platform::GetSharedModule(module_spec, process, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- }
- if (module_sp)
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return error;
-}
-
-bool PlatformWindows::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
- static SupportedArchList architectures;
-
- if (idx >= architectures.Count())
- return false;
- arch = architectures[idx];
- return true;
-}
-
-void PlatformWindows::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
-
-#ifdef _WIN32
- llvm::VersionTuple version = HostInfo::GetOSVersion();
- strm << "Host: Windows " << version.getAsString() << '\n';
-#endif
-}
-
-bool PlatformWindows::CanDebugProcess() { return true; }
-
-Environment PlatformWindows::GetEnvironment() {
- if (IsRemote()) {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetEnvironment();
- return Environment();
- }
-
- return Host::GetEnvironment();
-}
-
-ConstString PlatformWindows::GetFullNameForDylib(ConstString basename) {
- if (basename.IsEmpty())
- return basename;
-
- StreamString stream;
- stream.Printf("%s.dll", basename.GetCString());
- return ConstString(stream.GetString());
-}
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.h b/source/Plugins/Platform/Windows/PlatformWindows.h
deleted file mode 100644
index f7f55049e4e75..0000000000000
--- a/source/Plugins/Platform/Windows/PlatformWindows.h
+++ /dev/null
@@ -1,133 +0,0 @@
-//===-- PlatformWindows.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_PlatformWindows_h_
-#define liblldb_PlatformWindows_h_
-
-#include "lldb/Target/Platform.h"
-
-namespace lldb_private {
-
-class PlatformWindows : public Platform {
-public:
- PlatformWindows(bool is_host);
-
- ~PlatformWindows() override;
-
- static void Initialize();
-
- static void Terminate();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP CreateInstance(bool force,
- const lldb_private::ArchSpec *arch);
-
- static lldb_private::ConstString GetPluginNameStatic(bool is_host);
-
- static const char *GetPluginDescriptionStatic(bool is_host);
-
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override { return 1; }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- bool GetModuleSpec(const lldb_private::FileSpec &module_file_spec,
- const lldb_private::ArchSpec &arch,
- lldb_private::ModuleSpec &module_spec) override;
-
- Status
- ResolveExecutable(const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr) override;
-
- const char *GetDescription() override {
- return GetPluginDescriptionStatic(IsHost());
- }
-
- bool GetRemoteOSVersion() override;
-
- bool GetRemoteOSBuildString(std::string &s) override;
-
- bool GetRemoteOSKernelDescription(std::string &s) override;
-
- // Remote Platform subclasses need to override this function
- lldb_private::ArchSpec GetRemoteSystemArchitecture() override;
-
- bool IsConnected() const override;
-
- lldb_private::Status ConnectRemote(lldb_private::Args &args) override;
-
- lldb_private::Status DisconnectRemote() override;
-
- const char *GetHostname() override;
-
- const char *GetUserName(uint32_t uid) override;
-
- const char *GetGroupName(uint32_t gid) override;
-
- bool GetProcessInfo(lldb::pid_t pid,
- lldb_private::ProcessInstanceInfo &proc_info) override;
-
- uint32_t
- FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- lldb_private::Status
- LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
-
- lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Status &error) override;
-
- lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Status &error) override;
-
- lldb_private::Status
- GetFileWithUUID(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid,
- lldb_private::FileSpec &local_file) override;
-
- lldb_private::Status
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- bool CanDebugProcess() override;
-
- Environment GetEnvironment() override;
-
- // FIXME not sure what the _sigtramp equivalent would be on this platform
- void CalculateTrapHandlerSymbolNames() override {}
-
- ConstString GetFullNameForDylib(ConstString basename) override;
-
-protected:
- lldb::PlatformSP m_remote_platform_sp;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(PlatformWindows);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_PlatformWindows_h_
diff --git a/source/Plugins/Platform/gdb-server/CMakeLists.txt b/source/Plugins/Platform/gdb-server/CMakeLists.txt
deleted file mode 100644
index 2e3302590b443..0000000000000
--- a/source/Plugins/Platform/gdb-server/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginPlatformGDB PLUGIN
- PlatformRemoteGDBServer.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbTarget
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/Process/CMakeLists.txt b/source/Plugins/Process/CMakeLists.txt
deleted file mode 100644
index fdeb211fe7a20..0000000000000
--- a/source/Plugins/Process/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
- add_subdirectory(Linux)
- add_subdirectory(POSIX)
-elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- add_subdirectory(FreeBSD)
- add_subdirectory(POSIX)
-elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- add_subdirectory(NetBSD)
- add_subdirectory(POSIX)
-elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
- add_subdirectory(Windows/Common)
-elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- add_subdirectory(MacOSX-Kernel)
-endif()
-add_subdirectory(gdb-remote)
-add_subdirectory(Utility)
-add_subdirectory(elf-core)
-add_subdirectory(mach-core)
-add_subdirectory(minidump)
diff --git a/source/Plugins/Process/FreeBSD/CMakeLists.txt b/source/Plugins/Process/FreeBSD/CMakeLists.txt
deleted file mode 100644
index c8301f350e076..0000000000000
--- a/source/Plugins/Process/FreeBSD/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-add_lldb_library(lldbPluginProcessFreeBSD PLUGIN
- ProcessFreeBSD.cpp
- FreeBSDThread.cpp
- ProcessMonitor.cpp
-
- POSIXStopInfo.cpp
- RegisterContextPOSIXProcessMonitor_arm.cpp
- RegisterContextPOSIXProcessMonitor_arm64.cpp
- RegisterContextPOSIXProcessMonitor_powerpc.cpp
- RegisterContextPOSIXProcessMonitor_x86.cpp
- RegisterContextPOSIXProcessMonitor_mips64.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessUtility
- lldbPluginProcessPOSIX
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Linux/CMakeLists.txt b/source/Plugins/Process/Linux/CMakeLists.txt
deleted file mode 100644
index b4b4c401a271f..0000000000000
--- a/source/Plugins/Process/Linux/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-add_lldb_library(lldbPluginProcessLinux PLUGIN
- NativeProcessLinux.cpp
- NativeRegisterContextLinux.cpp
- NativeRegisterContextLinux_arm.cpp
- NativeRegisterContextLinux_arm64.cpp
- NativeRegisterContextLinux_mips64.cpp
- NativeRegisterContextLinux_ppc64le.cpp
- NativeRegisterContextLinux_s390x.cpp
- NativeRegisterContextLinux_x86_64.cpp
- NativeThreadLinux.cpp
- ProcessorTrace.cpp
- SingleStepCheck.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessPOSIX
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
deleted file mode 100644
index 8c6c95380e814..0000000000000
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ /dev/null
@@ -1,2097 +0,0 @@
-//===-- NativeProcessLinux.cpp -------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeProcessLinux.h"
-
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <fstream>
-#include <mutex>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-
-#include "lldb/Core/EmulateInstruction.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/common/NativeRegisterContext.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Host/linux/Uio.h"
-#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StringExtractor.h"
-#include "llvm/Support/Errno.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Threading.h"
-
-#include "NativeThreadLinux.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/LinuxProcMaps.h"
-#include "Procfs.h"
-
-#include <linux/unistd.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/user.h>
-#include <sys/wait.h>
-
-// Support hardware breakpoints in case it has not been defined
-#ifndef TRAP_HWBKPT
-#define TRAP_HWBKPT 4
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-using namespace llvm;
-
-// Private bits we only need internally.
-
-static bool ProcessVmReadvSupported() {
- static bool is_supported;
- static llvm::once_flag flag;
-
- llvm::call_once(flag, [] {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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 (is_supported)
- LLDB_LOG(log,
- "Detected kernel support for process_vm_readv syscall. "
- "Fast memory reads enabled.");
- else
- LLDB_LOG(log,
- "syscall process_vm_readv failed (error: {0}). Fast memory "
- "reads disabled.",
- llvm::sys::StrError());
- });
-
- return is_supported;
-}
-
-namespace {
-void MaybeLogLaunchInfo(const ProcessLaunchInfo &info) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- if (!log)
- return;
-
- if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
- LLDB_LOG(log, "setting STDIN to '{0}'", action->GetFileSpec());
- else
- LLDB_LOG(log, "leaving STDIN as is");
-
- if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
- LLDB_LOG(log, "setting STDOUT to '{0}'", action->GetFileSpec());
- else
- LLDB_LOG(log, "leaving STDOUT as is");
-
- if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
- LLDB_LOG(log, "setting STDERR to '{0}'", action->GetFileSpec());
- else
- LLDB_LOG(log, "leaving STDERR as is");
-
- int i = 0;
- for (const char **args = info.GetArguments().GetConstArgumentVector(); *args;
- ++args, ++i)
- LLDB_LOG(log, "arg {0}: '{1}'", i, *args);
-}
-
-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) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- if (!log)
- return;
- StreamString buf;
-
- switch (req) {
- case PTRACE_POKETEXT: {
- DisplayBytes(buf, &data, 8);
- LLDB_LOGV(log, "PTRACE_POKETEXT {0}", buf.GetData());
- break;
- }
- case PTRACE_POKEDATA: {
- DisplayBytes(buf, &data, 8);
- LLDB_LOGV(log, "PTRACE_POKEDATA {0}", buf.GetData());
- break;
- }
- case PTRACE_POKEUSER: {
- DisplayBytes(buf, &data, 8);
- LLDB_LOGV(log, "PTRACE_POKEUSER {0}", buf.GetData());
- break;
- }
- case PTRACE_SETREGS: {
- DisplayBytes(buf, data, data_size);
- LLDB_LOGV(log, "PTRACE_SETREGS {0}", buf.GetData());
- break;
- }
- case PTRACE_SETFPREGS: {
- DisplayBytes(buf, data, data_size);
- LLDB_LOGV(log, "PTRACE_SETFPREGS {0}", buf.GetData());
- break;
- }
- case PTRACE_SETSIGINFO: {
- DisplayBytes(buf, data, sizeof(siginfo_t));
- LLDB_LOGV(log, "PTRACE_SETSIGINFO {0}", 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);
- LLDB_LOGV(log, "PTRACE_SETREGSET {0}", 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 Status EnsureFDFlags(int fd, int flags) {
- Status 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
-// -----------------------------------------------------------------------------
-
-llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
-NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info,
- NativeDelegate &native_delegate,
- MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- MaybeLogLaunchInfo(launch_info);
-
- Status status;
- ::pid_t pid = ProcessLauncherPosixFork()
- .LaunchProcess(launch_info, status)
- .GetProcessId();
- LLDB_LOG(log, "pid = {0:x}", pid);
- if (status.Fail()) {
- LLDB_LOG(log, "failed to launch process: {0}", status);
- return status.ToError();
- }
-
- // Wait for the child process to trap on its call to execve.
- int wstatus;
- ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
- assert(wpid == pid);
- (void)wpid;
- if (!WIFSTOPPED(wstatus)) {
- LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
- WaitStatus::Decode(wstatus));
- return llvm::make_error<StringError>("Could not sync with inferior process",
- llvm::inconvertibleErrorCode());
- }
- LLDB_LOG(log, "inferior started, now in stopped state");
-
- ProcessInstanceInfo Info;
- if (!Host::GetProcessInfo(pid, Info)) {
- return llvm::make_error<StringError>("Cannot get process architecture",
- llvm::inconvertibleErrorCode());
- }
-
- // Set the architecture to the exe architecture.
- LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
- Info.GetArchitecture().GetArchitectureName());
-
- status = SetDefaultPtraceOpts(pid);
- if (status.Fail()) {
- LLDB_LOG(log, "failed to set default ptrace options: {0}", status);
- return status.ToError();
- }
-
- return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
- pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
- Info.GetArchitecture(), mainloop, {pid}));
-}
-
-llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
-NativeProcessLinux::Factory::Attach(
- lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid = {0:x}", pid);
-
- // Retrieve the architecture for the running process.
- ProcessInstanceInfo Info;
- if (!Host::GetProcessInfo(pid, Info)) {
- return llvm::make_error<StringError>("Cannot get process architecture",
- llvm::inconvertibleErrorCode());
- }
-
- auto tids_or = NativeProcessLinux::Attach(pid);
- if (!tids_or)
- return tids_or.takeError();
-
- return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
- pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
-}
-
-// -----------------------------------------------------------------------------
-// Public Instance Methods
-// -----------------------------------------------------------------------------
-
-NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
- NativeDelegate &delegate,
- const ArchSpec &arch, MainLoop &mainloop,
- llvm::ArrayRef<::pid_t> tids)
- : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
- if (m_terminal_fd != -1) {
- Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
- assert(status.Success());
- }
-
- Status status;
- m_sigchld_handle = mainloop.RegisterSignal(
- SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
- assert(m_sigchld_handle && status.Success());
-
- for (const auto &tid : tids) {
- NativeThreadLinux &thread = AddThread(tid);
- thread.SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(thread);
- }
-
- // Let our process instance know the thread has stopped.
- SetCurrentThreadID(tids[0]);
- SetState(StateType::eStateStopped, false);
-
- // Proccess any signals we received before installing our handler
- SigchldHandler();
-}
-
-llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- Status status;
- // Use a map to keep track of the threads which we have attached/need to
- // attach.
- Host::TidMap tids_to_attach;
- 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.
- if ((status = PtraceWrapper(PTRACE_ATTACH, tid)).Fail()) {
- // No such thread. The thread may have exited. More error handling
- // may be needed.
- if (status.GetError() == ESRCH) {
- it = tids_to_attach.erase(it);
- continue;
- }
- return status.ToError();
- }
-
- int wpid =
- llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, nullptr, __WALL);
- // 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 (wpid < 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;
- }
- return llvm::errorCodeToError(
- std::error_code(errno, std::generic_category()));
- }
-
- if ((status = SetDefaultPtraceOpts(tid)).Fail())
- return status.ToError();
-
- LLDB_LOG(log, "adding tid = {0}", tid);
- it->second = true;
- }
-
- // move the loop forward
- ++it;
- }
- }
-
- size_t tid_count = tids_to_attach.size();
- if (tid_count == 0)
- return llvm::make_error<StringError>("No such process",
- llvm::inconvertibleErrorCode());
-
- std::vector<::pid_t> tids;
- tids.reserve(tid_count);
- for (const auto &p : tids_to_attach)
- tids.push_back(p.first);
- return std::move(tids);
-}
-
-Status 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);
-}
-
-// Handles all waitpid events from the inferior process.
-void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
- WaitStatus 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());
-
- // Handle when the thread exits.
- if (exited) {
- LLDB_LOG(log,
- "got exit signal({0}) , tid = {1} ({2} main thread), process "
- "state = {3}",
- signal, pid, is_main_thread ? "is" : "is not", GetState());
-
- // This is a thread that exited. Ensure we're not tracking it anymore.
- StopTrackingThread(pid);
-
- if (is_main_thread) {
- // The main thread exited. We're done monitoring. Report to delegate.
- SetExitStatus(status, true);
-
- // Notify delegate that our process has exited.
- SetState(StateType::eStateExited, true);
- }
- 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
- LLDB_LOG(log, "received notification about an unknown tid {0}.", pid);
-
- if (info_err.Fail()) {
- LLDB_LOG(log,
- "(tid {0}) GetSignalInfo failed ({1}). "
- "Ingoring this notification.",
- pid, info_err);
- return;
- }
-
- LLDB_LOG(log, "tid {0}, si_code: {1}, si_pid: {2}", pid, info.si_code,
- info.si_pid);
-
- NativeThreadLinux &thread = AddThread(pid);
-
- // Resume the newly created thread.
- ResumeThread(thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(thread);
- 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);
- } 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.
- LLDB_LOG(log,
- "received a group stop for pid {0} tid {1}. Transparent "
- "handling of group stops not supported, resuming the "
- "thread.",
- 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);
-
- LLDB_LOG(log,
- "GetSignalInfo failed: {0}, tid = {1}, signal = {2}, "
- "status = {3}, main_thread = {4}, thread_found: {5}",
- info_err, pid, signal, status, is_main_thread, thread_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(status, 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?
- LLDB_LOG(log,
- "pid {0} tid {1} non-main thread exit occurred, didn't "
- "tell delegate anything since thread disappeared out "
- "from underneath us",
- GetID(), pid);
- }
- }
- }
-}
-
-void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- if (GetThreadByID(tid)) {
- // 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;
- LLDB_LOG(log,
- "received thread creation event for tid {0}. tid not tracked "
- "yet, waiting for thread to appear...",
- tid);
- ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, &status, __WALL);
- // 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) {
- LLDB_LOG(log,
- "waiting for tid {0} failed. Assuming the thread has "
- "disappeared in the meantime",
- 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)) {
- LLDB_LOG(log,
- "waiting for tid {0} returned an 'exited' event. Not "
- "tracking the thread.",
- tid);
- // Also a very improbable event.
- return;
- }
-
- LLDB_LOG(log, "pid = {0}: tracking new thread tid {1}", GetID(), tid);
- NativeThreadLinux &new_thread = AddThread(tid);
-
- ResumeThread(new_thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(new_thread);
-}
-
-void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
- NativeThreadLinux &thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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()) {
- LLDB_LOG(log,
- "pid {0} received thread creation event but "
- "GetEventMessage failed so we don't know the new tid",
- thread.GetID());
- } else
- WaitForNewThread(event_message);
-
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
- }
-
- case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
- LLDB_LOG(log, "received exec event, code = {0}", 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.
- LLDB_LOG(log, "exec received, stop tracking all but main thread");
-
- for (auto i = m_threads.begin(); i != m_threads.end();) {
- if ((*i)->GetID() == GetID())
- i = m_threads.erase(i);
- else
- ++i;
- }
- assert(m_threads.size() == 1);
- auto *main_thread = static_cast<NativeThreadLinux *>(m_threads[0].get());
-
- SetCurrentThreadID(main_thread->GetID());
- main_thread->SetStoppedByExec();
-
- // Tell coordinator about about the "new" (since exec) stopped main thread.
- ThreadWasCreated(*main_thread);
-
- // Let our delegate know we have just exec'd.
- NotifyDidExec();
-
- // Let the process know we're stopped.
- StopRunningThreads(main_thread->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;
-
- LLDB_LOG(log,
- "received PTRACE_EVENT_EXIT, data = {0:x}, WIFEXITED={1}, "
- "WIFSIGNALED={2}, pid = {3}, main_thread = {4}",
- data, WIFEXITED(data), WIFSIGNALED(data), thread.GetID(),
- is_main_thread);
-
-
- 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;
- Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
- wp_index, (uintptr_t)info.si_addr);
- if (error.Fail())
- LLDB_LOG(log,
- "received error while checking for watchpoint hits, pid = "
- "{0}, error = {1}",
- thread.GetID(), error);
- if (wp_index != LLDB_INVALID_INDEX32) {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
-
- // If a breakpoint was hit, report it
- uint32_t bp_index;
- error = thread.GetRegisterContext().GetHardwareBreakHitIndex(
- bp_index, (uintptr_t)info.si_addr);
- if (error.Fail())
- LLDB_LOG(log, "received error while checking for hardware "
- "breakpoint hits, pid = {0}, error = {1}",
- thread.GetID(), error);
- if (bp_index != LLDB_INVALID_INDEX32) {
- MonitorBreakpoint(thread);
- 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;
- Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
- wp_index, LLDB_INVALID_ADDRESS);
- if (error.Fail())
- LLDB_LOG(log,
- "received error while checking for watchpoint hits, pid = "
- "{0}, error = {1}",
- thread.GetID(), error);
- if (wp_index != LLDB_INVALID_INDEX32) {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
- }
-// NO BREAK
-#endif
- case TRAP_BRKPT:
- MonitorBreakpoint(thread);
- break;
-
- case SIGTRAP:
- case (SIGTRAP | 0x80):
- LLDB_LOG(
- log,
- "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}, resuming",
- info.si_code, GetID(), thread.GetID());
-
- // Ignore these signals until we know more about them.
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
-
- default:
- LLDB_LOG(log, "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}",
- info.si_code, GetID(), thread.GetID());
- MonitorSignal(info, thread, false);
- break;
- }
-}
-
-void NativeProcessLinux::MonitorTrace(NativeThreadLinux &thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "received trace event, pid = {0}", thread.GetID());
-
- // This thread is currently stopped.
- thread.SetStoppedByTrace();
-
- StopRunningThreads(thread.GetID());
-}
-
-void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) {
- Log *log(
- GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
- LLDB_LOG(log, "received breakpoint event, pid = {0}", thread.GetID());
-
- // Mark the thread as stopped at breakpoint.
- thread.SetStoppedByBreakpoint();
- FixupBreakpointPCAsNeeded(thread);
-
- if (m_threads_stepping_with_breakpoint.find(thread.GetID()) !=
- m_threads_stepping_with_breakpoint.end())
- thread.SetStoppedByTrace();
-
- StopRunningThreads(thread.GetID());
-}
-
-void NativeProcessLinux::MonitorWatchpoint(NativeThreadLinux &thread,
- uint32_t wp_index) {
- Log *log(
- GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS));
- LLDB_LOG(log, "received watchpoint event, pid = {0}, wp_index = {1}",
- 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);
-
- // 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(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 Linux.
- //
- // IOW, user generated signals never generate what we consider to be a
- // "crash".
- //
- // Similarly, ACK signals generated by this monitor.
-
- // Handle the signal.
- LLDB_LOG(log,
- "received signal {0} ({1}) with code {2}, (siginfo pid = {3}, "
- "waitpid pid = {4})",
- Host::GetSignalAsCString(signo), signo, info.si_code,
- thread.GetID());
-
- // Check for thread stop notification.
- if (is_from_llgs && (info.si_code == SI_TKILL) && (signo == SIGSTOP)) {
- // This is a tgkill()-based stop.
- LLDB_LOG(log, "pid {0} tid {1}, thread stopped", 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.
- Status error = ResumeThread(thread, thread.GetState(), 0);
- if (error.Fail())
- LLDB_LOG(log, "failed to resume thread {0}: {1}", thread.GetID(),
- error);
- }
- } else {
- LLDB_LOG(log,
- "pid {0} tid {1}, thread was already marked as a stopped "
- "state (state={2}), leaving stop signal as is",
- GetID(), thread.GetID(), thread_state);
- SignalIfAllThreadsStopped();
- }
-
- // Done handling.
- return;
- }
-
- // Check if debugger should stop at this signal or just ignore it and resume
- // the inferior.
- if (m_signals_to_ignore.find(signo) != m_signals_to_ignore.end()) {
- ResumeThread(thread, thread.GetState(), signo);
- return;
- }
-
- // This thread is stopped.
- LLDB_LOG(log, "received signal {0}", Host::GetSignalAsCString(signo));
- 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;
-
- // 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) {}
-};
-
-} // 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);
-
- 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;
- }
-
- // 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]);
-
- Status error =
- emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
-
- 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 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);
-}
-
-Status
-NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
- Status error;
- NativeRegisterContext& register_context = thread.GetRegisterContext();
-
- std::unique_ptr<EmulateInstruction> emulator_ap(
- EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying,
- nullptr));
-
- if (emulator_ap == nullptr)
- return Status("Instruction emulator not found!");
-
- EmulatorBaton baton(*this, register_context);
- 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 Status("Read instruction failed!");
-
- bool emulation_result =
- emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
-
- const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *reg_info_flags = register_context.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]);
-
- 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);
- } 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.GetPC() + emulator_ap->GetOpcode().GetByteSize();
- next_flags = ReadFlags(register_context);
- } 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 Status("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 ||
- m_arch.GetMachine() == llvm::Triple::ppc64le)
- 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 Status();
- } else if (error.Fail())
- return error;
-
- m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
-
- return Status();
-}
-
-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;
-}
-
-Status NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid {0}", GetID());
-
- bool software_single_step = !SupportHardwareSingleStepping();
-
- if (software_single_step) {
- for (const auto &thread : m_threads) {
- assert(thread && "thread list should not contain NULL threads");
-
- const ResumeAction *const action =
- resume_actions.GetActionForThread(thread->GetID(), true);
- if (action == nullptr)
- continue;
-
- if (action->state == eStateStepping) {
- Status error = SetupSoftwareSingleStepping(
- static_cast<NativeThreadLinux &>(*thread));
- if (error.Fail())
- return error;
- }
- }
- }
-
- for (const auto &thread : m_threads) {
- assert(thread && "thread list should not contain NULL threads");
-
- const ResumeAction *const action =
- resume_actions.GetActionForThread(thread->GetID(), true);
-
- if (action == nullptr) {
- LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
- thread->GetID());
- continue;
- }
-
- LLDB_LOG(log, "processing resume action state {0} for pid {1} tid {2}",
- action->state, GetID(), thread->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), action->state,
- signo);
- break;
- }
-
- case eStateSuspended:
- case eStateStopped:
- llvm_unreachable("Unexpected state");
-
- default:
- return Status("NativeProcessLinux::%s (): unexpected state %s specified "
- "for pid %" PRIu64 ", tid %" PRIu64,
- __FUNCTION__, StateAsCString(action->state), GetID(),
- thread->GetID());
- }
- }
-
- return Status();
-}
-
-Status NativeProcessLinux::Halt() {
- Status error;
-
- if (kill(GetID(), SIGSTOP) != 0)
- error.SetErrorToErrno();
-
- return error;
-}
-
-Status NativeProcessLinux::Detach() {
- Status error;
-
- // Stop monitoring the inferior.
- m_sigchld_handle.reset();
-
- // Tell ptrace to detach from the process.
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- return error;
-
- for (const auto &thread : m_threads) {
- Status e = Detach(thread->GetID());
- if (e.Fail())
- error =
- e; // Save the error, but still attempt to detach from other threads.
- }
-
- m_processor_trace_monitor.clear();
- m_pt_proces_trace_id = LLDB_INVALID_UID;
-
- return error;
-}
-
-Status NativeProcessLinux::Signal(int signo) {
- Status error;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "sending signal {0} ({1}) to pid {1}", signo,
- Host::GetSignalAsCString(signo), GetID());
-
- if (kill(GetID(), signo))
- error.SetErrorToErrno();
-
- return error;
-}
-
-Status 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(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- NativeThreadProtocol *running_thread = nullptr;
- NativeThreadProtocol *stopped_thread = nullptr;
-
- LLDB_LOG(log, "selecting running thread for interrupt target");
- for (const auto &thread : m_threads) {
- // If we have a running or stepping thread, we'll call that the target of
- // the interrupt.
- const auto thread_state = thread->GetState();
- if (thread_state == eStateRunning || thread_state == eStateStepping) {
- running_thread = thread.get();
- break;
- } else if (!stopped_thread && 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 = thread.get();
- }
- }
-
- if (!running_thread && !stopped_thread) {
- Status error("found no running/stepping or live stopped threads as target "
- "for interrupt");
- LLDB_LOG(log, "skipping due to error: {0}", error);
-
- return error;
- }
-
- NativeThreadProtocol *deferred_signal_thread =
- running_thread ? running_thread : stopped_thread;
-
- LLDB_LOG(log, "pid {0} {1} tid {2} chosen for interrupt target", GetID(),
- running_thread ? "running" : "stopped",
- deferred_signal_thread->GetID());
-
- StopRunningThreads(deferred_signal_thread->GetID());
-
- return Status();
-}
-
-Status NativeProcessLinux::Kill() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid {0}", GetID());
-
- Status 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.
- LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
- 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;
- }
-
- return error;
-}
-
-Status 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.
-
- if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
- // We're done.
- return Status("unsupported");
- }
-
- Status error = PopulateMemoryRegionCache();
- if (error.Fail()) {
- return error;
- }
-
- 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->first;
-
- // 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();
- UNUSED_IF_ASSERT_DISABLED(prev_base_address);
-
- // 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;
-}
-
-Status NativeProcessLinux::PopulateMemoryRegionCache() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- // 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()) {
- LLDB_LOG(log, "reusing {0} cached memory region entries",
- m_mem_region_cache.size());
- return Status();
- }
-
- auto BufferOrError = getProcFile(GetID(), "maps");
- if (!BufferOrError) {
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- return BufferOrError.getError();
- }
- Status Result;
- ParseLinuxMapRegions(BufferOrError.get()->getBuffer(),
- [&](const MemoryRegionInfo &Info, const Status &ST) {
- if (ST.Success()) {
- FileSpec file_spec(Info.GetName().GetCString());
- FileSystem::Instance().Resolve(file_spec);
- m_mem_region_cache.emplace_back(Info, file_spec);
- return true;
- } else {
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- LLDB_LOG(log, "failed to parse proc maps: {0}", ST);
- Result = ST;
- return false;
- }
- });
- if (Result.Fail())
- return Result;
-
- 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.
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- LLDB_LOG(log,
- "failed to find any procfs maps entries, assuming no support "
- "for memory region metadata retrieval");
- return Status("not supported");
- }
-
- LLDB_LOG(log, "read {0} memory region entries from /proc/{1}/maps",
- m_mem_region_cache.size(), GetID());
-
- // We support memory retrieval, remember that.
- m_supports_mem_region = LazyBool::eLazyBoolYes;
- return Status();
-}
-
-void NativeProcessLinux::DoStopIDBumped(uint32_t newBumpId) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "newBumpId={0}", newBumpId);
- LLDB_LOG(log, "clearing {0} entries from memory region cache",
- m_mem_region_cache.size());
- m_mem_region_cache.clear();
-}
-
-Status 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 Status("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 Status();
- } else {
- addr = LLDB_INVALID_ADDRESS;
- return Status("unable to allocate %" PRIu64
- " bytes of memory with permissions %s",
- size, GetPermissionsAsCString(permissions));
- }
-#endif
-}
-
-Status NativeProcessLinux::DeallocateMemory(lldb::addr_t addr) {
- // FIXME see comments in AllocateMemory - required lower-level
- // bits not in place yet (ThreadPlans)
- return Status("not implemented");
-}
-
-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();
-}
-
-Status NativeProcessLinux::SetBreakpoint(lldb::addr_t addr, uint32_t size,
- bool hardware) {
- if (hardware)
- return SetHardwareBreakpoint(addr, size);
- else
- return SetSoftwareBreakpoint(addr, size);
-}
-
-Status NativeProcessLinux::RemoveBreakpoint(lldb::addr_t addr, bool hardware) {
- if (hardware)
- return RemoveHardwareBreakpoint(addr);
- else
- return NativeProcessProtocol::RemoveBreakpoint(addr);
-}
-
-llvm::Expected<llvm::ArrayRef<uint8_t>>
-NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
- // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
- // linux kernel does otherwise.
- static const uint8_t g_arm_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
- static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
-
- switch (GetArchitecture().GetMachine()) {
- case llvm::Triple::arm:
- switch (size_hint) {
- case 2:
- return llvm::makeArrayRef(g_thumb_opcode);
- case 4:
- return llvm::makeArrayRef(g_arm_opcode);
- default:
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Unrecognised trap opcode size hint!");
- }
- default:
- return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
- }
-}
-
-Status 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();
-
- 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;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log,
- "using process_vm_readv to read {0} bytes from inferior "
- "address {1:x}: {2}",
- size, addr, success ? "Success" : llvm::sys::StrError(errno));
-
- if (success)
- return Status();
- // 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_MEMORY));
- LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
-
- for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
- Status error = NativeProcessLinux::PtraceWrapper(
- PTRACE_PEEKDATA, GetID(), (void *)addr, nullptr, 0, &data);
- if (error.Fail())
- return error;
-
- 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);
-
- LLDB_LOG(log, "[{0:x}]:{1:x}", addr, data);
- addr += k_ptrace_word_size;
- dst += k_ptrace_word_size;
- }
- return Status();
-}
-
-Status 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;
- Status error;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
- LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", 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);
-
- LLDB_LOG(log, "[{0:x}]:{1:x}", addr, data);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(),
- (void *)addr, (void *)data);
- if (error.Fail())
- return error;
- } else {
- unsigned char buff[8];
- size_t bytes_read;
- error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read);
- if (error.Fail())
- 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())
- return error;
-
- LLDB_LOG(log, "[{0:x}]:{1:x} ({2:x})", addr, *(const unsigned long *)src,
- *(unsigned long *)buff);
- }
-
- addr += k_ptrace_word_size;
- src += k_ptrace_word_size;
- }
- return error;
-}
-
-Status NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo) {
- return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
-}
-
-Status NativeProcessLinux::GetEventMessage(lldb::tid_t tid,
- unsigned long *message) {
- return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message);
-}
-
-Status NativeProcessLinux::Detach(lldb::tid_t tid) {
- if (tid == LLDB_INVALID_THREAD_ID)
- return Status();
-
- return PtraceWrapper(PTRACE_DETACH, tid);
-}
-
-bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
- for (const auto &thread : m_threads) {
- assert(thread && "thread list should not contain NULL threads");
- if (thread->GetID() == thread_id) {
- // We have this thread.
- return true;
- }
- }
-
- // We don't have this thread.
- return false;
-}
-
-bool NativeProcessLinux::StopTrackingThread(lldb::tid_t thread_id) {
- Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "tid: {0})", thread_id);
-
- 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;
- }
- }
-
- if (found)
- StopTracingForThread(thread_id);
- SignalIfAllThreadsStopped();
- return found;
-}
-
-NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
-
- 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);
-
- m_threads.push_back(llvm::make_unique<NativeThreadLinux>(*this, thread_id));
-
- if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
- auto traceMonitor = ProcessorTraceMonitor::Create(
- GetID(), thread_id, m_pt_process_trace_config, true);
- if (traceMonitor) {
- m_pt_traced_thread_group.insert(thread_id);
- m_processor_trace_monitor.insert(
- std::make_pair(thread_id, std::move(*traceMonitor)));
- } else {
- LLDB_LOG(log, "failed to start trace on thread {0}", thread_id);
- Status error(traceMonitor.takeError());
- LLDB_LOG(log, "error {0}", error);
- }
- }
-
- return static_cast<NativeThreadLinux &>(*m_threads.back());
-}
-
-Status NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path,
- FileSpec &file_spec) {
- Status error = PopulateMemoryRegionCache();
- if (error.Fail())
- return error;
-
- FileSpec module_file_spec(module_path);
- FileSystem::Instance().Resolve(module_file_spec);
-
- file_spec.Clear();
- for (const auto &it : m_mem_region_cache) {
- if (it.second.GetFilename() == module_file_spec.GetFilename()) {
- file_spec = it.second;
- return Status();
- }
- }
- return Status("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
- module_file_spec.GetFilename().AsCString(), GetID());
-}
-
-Status NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name,
- lldb::addr_t &load_addr) {
- load_addr = LLDB_INVALID_ADDRESS;
- Status error = PopulateMemoryRegionCache();
- if (error.Fail())
- return error;
-
- FileSpec file(file_name);
- for (const auto &it : m_mem_region_cache) {
- if (it.second == file) {
- load_addr = it.first.GetRange().GetRangeBase();
- return Status();
- }
- }
- return Status("No load address found for specified file.");
-}
-
-NativeThreadLinux *NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
- return static_cast<NativeThreadLinux *>(
- NativeProcessProtocol::GetThreadByID(tid));
-}
-
-Status NativeProcessLinux::ResumeThread(NativeThreadLinux &thread,
- lldb::StateType state, int signo) {
- Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "tid: {0}", 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) {
- LLDB_LOG(log,
- "about to resume tid {0} per explicit request but we have a "
- "pending stop notification (tid {1}) that is actively "
- "waiting for this thread to stop. Valid sequence of events?",
- 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:
- LLDB_LOG(log, "Unhandled state {0}.", state);
- llvm_unreachable("Unhandled state for resume");
- }
-}
-
-//===----------------------------------------------------------------------===//
-
-void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) {
- Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "about to process event: (triggering_tid: {0})",
- triggering_tid);
-
- m_pending_notification_tid = triggering_tid;
-
- // 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 : m_threads) {
- if (StateIsRunningState(thread->GetState()))
- static_cast<NativeThreadLinux *>(thread.get())->RequestStop();
- }
-
- SignalIfAllThreadsStopped();
- LLDB_LOG(log, "event processing done");
-}
-
-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.
- }
-
- // We have a pending notification and all threads have stopped.
- Log *log(
- GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
-
- // Clear any temporary breakpoints we used to implement software single
- // stepping.
- for (const auto &thread_info : m_threads_stepping_with_breakpoint) {
- Status error = RemoveBreakpoint(thread_info.second);
- if (error.Fail())
- LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}",
- thread_info.first, error);
- }
- 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 = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "tid: {0}", 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(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- // Process all pending waitpid notifications.
- while (true) {
- int status = -1;
- ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, -1, &status,
- __WALL | __WNOTHREAD | WNOHANG);
-
- if (wait_pid == 0)
- break; // We are done.
-
- if (wait_pid == -1) {
- Status error(errno, eErrorTypePOSIX);
- LLDB_LOG(log, "waitpid (-1, &status, _) failed: {0}", error);
- break;
- }
-
- WaitStatus wait_status = WaitStatus::Decode(status);
- bool exited = wait_status.type == WaitStatus::Exit ||
- (wait_status.type == WaitStatus::Signal &&
- wait_pid == static_cast<::pid_t>(GetID()));
-
- LLDB_LOG(
- log,
- "waitpid (-1, &status, _) => pid = {0}, status = {1}, exited = {2}",
- wait_pid, wait_status, exited);
-
- MonitorCallback(wait_pid, exited, wait_status);
- }
-}
-
-// 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*)
-Status NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
- void *data, size_t data_size,
- long *result) {
- Status 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;
-
- LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3}, {4})={5:x}", req, pid, addr, data,
- data_size, ret);
-
- PtraceDisplayBytes(req, data, data_size);
-
- if (error.Fail())
- LLDB_LOG(log, "ptrace() failed: {0}", error);
-
- return error;
-}
-
-llvm::Expected<ProcessorTraceMonitor &>
-NativeProcessLinux::LookupProcessorTraceInstance(lldb::user_id_t traceid,
- lldb::tid_t thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- if (thread == LLDB_INVALID_THREAD_ID && traceid == m_pt_proces_trace_id) {
- LLDB_LOG(log, "thread not specified: {0}", traceid);
- return Status("tracing not active thread not specified").ToError();
- }
-
- for (auto& iter : m_processor_trace_monitor) {
- if (traceid == iter.second->GetTraceID() &&
- (thread == iter.first || thread == LLDB_INVALID_THREAD_ID))
- return *(iter.second);
- }
-
- LLDB_LOG(log, "traceid not being traced: {0}", traceid);
- return Status("tracing not active for this thread").ToError();
-}
-
-Status NativeProcessLinux::GetMetaData(lldb::user_id_t traceid,
- lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- TraceOptions trace_options;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- Status error;
-
- LLDB_LOG(log, "traceid {0}", traceid);
-
- auto perf_monitor = LookupProcessorTraceInstance(traceid, thread);
- if (!perf_monitor) {
- LLDB_LOG(log, "traceid not being traced: {0}", traceid);
- buffer = buffer.slice(buffer.size());
- error = perf_monitor.takeError();
- return error;
- }
- return (*perf_monitor).ReadPerfTraceData(buffer, offset);
-}
-
-Status NativeProcessLinux::GetData(lldb::user_id_t traceid, lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- Status error;
-
- LLDB_LOG(log, "traceid {0}", traceid);
-
- auto perf_monitor = LookupProcessorTraceInstance(traceid, thread);
- if (!perf_monitor) {
- LLDB_LOG(log, "traceid not being traced: {0}", traceid);
- buffer = buffer.slice(buffer.size());
- error = perf_monitor.takeError();
- return error;
- }
- return (*perf_monitor).ReadPerfTraceAux(buffer, offset);
-}
-
-Status NativeProcessLinux::GetTraceConfig(lldb::user_id_t traceid,
- TraceOptions &config) {
- Status error;
- if (config.getThreadID() == LLDB_INVALID_THREAD_ID &&
- m_pt_proces_trace_id == traceid) {
- if (m_pt_proces_trace_id == LLDB_INVALID_UID) {
- error.SetErrorString("tracing not active for this process");
- return error;
- }
- config = m_pt_process_trace_config;
- } else {
- auto perf_monitor =
- LookupProcessorTraceInstance(traceid, config.getThreadID());
- if (!perf_monitor) {
- error = perf_monitor.takeError();
- return error;
- }
- error = (*perf_monitor).GetTraceConfig(config);
- }
- return error;
-}
-
-lldb::user_id_t
-NativeProcessLinux::StartTraceGroup(const TraceOptions &config,
- Status &error) {
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- if (config.getType() != TraceType::eTraceTypeProcessorTrace)
- return LLDB_INVALID_UID;
-
- if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
- error.SetErrorString("tracing already active on this process");
- return m_pt_proces_trace_id;
- }
-
- for (const auto &thread_sp : m_threads) {
- if (auto traceInstance = ProcessorTraceMonitor::Create(
- GetID(), thread_sp->GetID(), config, true)) {
- m_pt_traced_thread_group.insert(thread_sp->GetID());
- m_processor_trace_monitor.insert(
- std::make_pair(thread_sp->GetID(), std::move(*traceInstance)));
- }
- }
-
- m_pt_process_trace_config = config;
- error = ProcessorTraceMonitor::GetCPUType(m_pt_process_trace_config);
-
- // Trace on Complete process will have traceid of 0
- m_pt_proces_trace_id = 0;
-
- LLDB_LOG(log, "Process Trace ID {0}", m_pt_proces_trace_id);
- return m_pt_proces_trace_id;
-}
-
-lldb::user_id_t NativeProcessLinux::StartTrace(const TraceOptions &config,
- Status &error) {
- if (config.getType() != TraceType::eTraceTypeProcessorTrace)
- return NativeProcessProtocol::StartTrace(config, error);
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- lldb::tid_t threadid = config.getThreadID();
-
- if (threadid == LLDB_INVALID_THREAD_ID)
- return StartTraceGroup(config, error);
-
- auto thread_sp = GetThreadByID(threadid);
- if (!thread_sp) {
- // Thread not tracked by lldb so don't trace.
- error.SetErrorString("invalid thread id");
- return LLDB_INVALID_UID;
- }
-
- const auto &iter = m_processor_trace_monitor.find(threadid);
- if (iter != m_processor_trace_monitor.end()) {
- LLDB_LOG(log, "Thread already being traced");
- error.SetErrorString("tracing already active on this thread");
- return LLDB_INVALID_UID;
- }
-
- auto traceMonitor =
- ProcessorTraceMonitor::Create(GetID(), threadid, config, false);
- if (!traceMonitor) {
- error = traceMonitor.takeError();
- LLDB_LOG(log, "error {0}", error);
- return LLDB_INVALID_UID;
- }
- lldb::user_id_t ret_trace_id = (*traceMonitor)->GetTraceID();
- m_processor_trace_monitor.insert(
- std::make_pair(threadid, std::move(*traceMonitor)));
- return ret_trace_id;
-}
-
-Status NativeProcessLinux::StopTracingForThread(lldb::tid_t thread) {
- Status error;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- LLDB_LOG(log, "Thread {0}", thread);
-
- const auto& iter = m_processor_trace_monitor.find(thread);
- if (iter == m_processor_trace_monitor.end()) {
- error.SetErrorString("tracing not active for this thread");
- return error;
- }
-
- if (iter->second->GetTraceID() == m_pt_proces_trace_id) {
- // traceid maps to the whole process so we have to erase it from the thread
- // group.
- LLDB_LOG(log, "traceid maps to process");
- m_pt_traced_thread_group.erase(thread);
- }
- m_processor_trace_monitor.erase(iter);
-
- return error;
-}
-
-Status NativeProcessLinux::StopTrace(lldb::user_id_t traceid,
- lldb::tid_t thread) {
- Status error;
-
- TraceOptions trace_options;
- trace_options.setThreadID(thread);
- error = NativeProcessLinux::GetTraceConfig(traceid, trace_options);
-
- if (error.Fail())
- return error;
-
- switch (trace_options.getType()) {
- case lldb::TraceType::eTraceTypeProcessorTrace:
- if (traceid == m_pt_proces_trace_id &&
- thread == LLDB_INVALID_THREAD_ID)
- StopProcessorTracingOnProcess();
- else
- error = StopProcessorTracingOnThread(traceid, thread);
- break;
- default:
- error.SetErrorString("trace not supported");
- break;
- }
-
- return error;
-}
-
-void NativeProcessLinux::StopProcessorTracingOnProcess() {
- for (auto thread_id_iter : m_pt_traced_thread_group)
- m_processor_trace_monitor.erase(thread_id_iter);
- m_pt_traced_thread_group.clear();
- m_pt_proces_trace_id = LLDB_INVALID_UID;
-}
-
-Status NativeProcessLinux::StopProcessorTracingOnThread(lldb::user_id_t traceid,
- lldb::tid_t thread) {
- Status error;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- if (thread == LLDB_INVALID_THREAD_ID) {
- for (auto& iter : m_processor_trace_monitor) {
- if (iter.second->GetTraceID() == traceid) {
- // Stopping a trace instance for an individual thread hence there will
- // only be one traceid that can match.
- m_processor_trace_monitor.erase(iter.first);
- return error;
- }
- LLDB_LOG(log, "Trace ID {0}", iter.second->GetTraceID());
- }
-
- LLDB_LOG(log, "Invalid TraceID");
- error.SetErrorString("invalid trace id");
- return error;
- }
-
- // thread is specified so we can use find function on the map.
- const auto& iter = m_processor_trace_monitor.find(thread);
- if (iter == m_processor_trace_monitor.end()) {
- // thread not found in our map.
- LLDB_LOG(log, "thread not being traced");
- error.SetErrorString("tracing not active for this thread");
- return error;
- }
- if (iter->second->GetTraceID() != traceid) {
- // traceid did not match so it has to be invalid.
- LLDB_LOG(log, "Invalid TraceID");
- error.SetErrorString("invalid trace id");
- return error;
- }
-
- LLDB_LOG(log, "UID - {0} , Thread -{1}", traceid, thread);
-
- if (traceid == m_pt_proces_trace_id) {
- // traceid maps to the whole process so we have to erase it from the thread
- // group.
- LLDB_LOG(log, "traceid maps to process");
- m_pt_traced_thread_group.erase(thread);
- }
- m_processor_trace_monitor.erase(iter);
-
- return error;
-}
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
deleted file mode 100644
index 69f2b528d3300..0000000000000
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ /dev/null
@@ -1,261 +0,0 @@
-//===-- NativeProcessLinux.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_NativeProcessLinux_H_
-#define liblldb_NativeProcessLinux_H_
-
-#include <csignal>
-#include <unordered_set>
-
-#include "lldb/Host/Debug.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/linux/Support.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-types.h"
-
-#include "NativeThreadLinux.h"
-#include "ProcessorTrace.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
-
-namespace lldb_private {
-class Status;
-class Scalar;
-
-namespace process_linux {
-/// @class NativeProcessLinux
-/// 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 {
-public:
- class Factory : public NativeProcessProtocol::Factory {
- public:
- llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
- Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
- MainLoop &mainloop) const override;
-
- llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
- Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
- MainLoop &mainloop) const override;
- };
-
- // ---------------------------------------------------------------------
- // NativeProcessProtocol Interface
- // ---------------------------------------------------------------------
- Status Resume(const ResumeActionList &resume_actions) override;
-
- Status Halt() override;
-
- Status Detach() override;
-
- Status Signal(int signo) override;
-
- Status Interrupt() override;
-
- Status Kill() override;
-
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
- Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
- size_t &bytes_read) override;
-
- Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
- size_t &bytes_written) override;
-
- Status AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) override;
-
- Status DeallocateMemory(lldb::addr_t addr) override;
-
- lldb::addr_t GetSharedLibraryInfoAddress() override;
-
- size_t UpdateThreads() override;
-
- const ArchSpec &GetArchitecture() const override { return m_arch; }
-
- Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
- bool hardware) override;
-
- Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override;
-
- void DoStopIDBumped(uint32_t newBumpId) override;
-
- Status GetLoadedModuleFileSpec(const char *module_path,
- FileSpec &file_spec) override;
-
- Status GetFileLoadAddress(const llvm::StringRef &file_name,
- lldb::addr_t &load_addr) override;
-
- NativeThreadLinux *GetThreadByID(lldb::tid_t id);
-
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- GetAuxvData() const override {
- return getProcFile(GetID(), "auxv");
- }
-
- lldb::user_id_t StartTrace(const TraceOptions &config,
- Status &error) override;
-
- Status StopTrace(lldb::user_id_t traceid,
- lldb::tid_t thread) override;
-
- Status GetData(lldb::user_id_t traceid, lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) override;
-
- Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) override;
-
- Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) override;
-
- // ---------------------------------------------------------------------
- // Interface used by NativeRegisterContext-derived classes.
- // ---------------------------------------------------------------------
- static Status 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:
- llvm::Expected<llvm::ArrayRef<uint8_t>>
- GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
-
-private:
- MainLoop::SignalHandleUP m_sigchld_handle;
- ArchSpec m_arch;
-
- LazyBool m_supports_mem_region = eLazyBoolCalculate;
- std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
-
- lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-
- // 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(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
- const ArchSpec &arch, MainLoop &mainloop,
- llvm::ArrayRef<::pid_t> tids);
-
- // Returns a list of process threads that we have attached to.
- static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
-
- static Status SetDefaultPtraceOpts(const lldb::pid_t);
-
- void MonitorCallback(lldb::pid_t pid, bool exited, WaitStatus status);
-
- void WaitForNewThread(::pid_t tid);
-
- void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
-
- void MonitorTrace(NativeThreadLinux &thread);
-
- void MonitorBreakpoint(NativeThreadLinux &thread);
-
- void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
-
- void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread,
- bool exited);
-
- Status SetupSoftwareSingleStepping(NativeThreadLinux &thread);
-
- bool HasThreadNoLock(lldb::tid_t thread_id);
-
- bool StopTrackingThread(lldb::tid_t thread_id);
-
- NativeThreadLinux &AddThread(lldb::tid_t thread_id);
-
- /// Writes a siginfo_t structure corresponding to the given thread ID to the
- /// memory region pointed to by @p siginfo.
- Status 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.
- Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
-
- void NotifyThreadDeath(lldb::tid_t tid);
-
- Status 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.
- Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
- int signo);
-
- void ThreadWasCreated(NativeThreadLinux &thread);
-
- void SigchldHandler();
-
- Status PopulateMemoryRegionCache();
-
- lldb::user_id_t StartTraceGroup(const TraceOptions &config,
- Status &error);
-
- // This function is intended to be used to stop tracing
- // on a thread that exited.
- Status StopTracingForThread(lldb::tid_t thread);
-
- // The below function as the name suggests, looks up a ProcessorTrace
- // instance from the m_processor_trace_monitor map. In the case of
- // process tracing where the traceid passed would map to the complete
- // process, it is mandatory to provide a threadid to obtain a trace
- // instance (since ProcessorTrace is tied to a thread). In the other
- // scenario that an individual thread is being traced, just the traceid
- // is sufficient to obtain the actual ProcessorTrace instance.
- llvm::Expected<ProcessorTraceMonitor &>
- LookupProcessorTraceInstance(lldb::user_id_t traceid, lldb::tid_t thread);
-
- // Stops tracing on individual threads being traced. Not intended
- // to be used to stop tracing on complete process.
- Status StopProcessorTracingOnThread(lldb::user_id_t traceid,
- lldb::tid_t thread);
-
- // Intended to stop tracing on complete process.
- // Should not be used for stopping trace on
- // individual threads.
- void StopProcessorTracingOnProcess();
-
- llvm::DenseMap<lldb::tid_t, ProcessorTraceMonitorUP>
- m_processor_trace_monitor;
-
- // Set for tracking threads being traced under
- // same process user id.
- llvm::DenseSet<lldb::tid_t> m_pt_traced_thread_group;
-
- lldb::user_id_t m_pt_proces_trace_id = LLDB_INVALID_UID;
- TraceOptions m_pt_process_trace_config;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef liblldb_NativeProcessLinux_H_
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
deleted file mode 100644
index 79f635c88985b..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-//===-- NativeRegisterContextLinux.cpp --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeRegisterContextLinux.h"
-
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-NativeRegisterContextLinux::NativeRegisterContextLinux(
- NativeThreadProtocol &native_thread,
- RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(native_thread, reg_info_interface_p) {}
-
-lldb::ByteOrder NativeRegisterContextLinux::GetByteOrder() const {
- return m_thread.GetProcess().GetByteOrder();
-}
-
-Status NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index,
- RegisterValue &reg_value) {
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Status("register %" PRIu32 " not found", reg_index);
-
- return DoReadRegisterValue(reg_info->byte_offset, reg_info->name,
- reg_info->byte_size, reg_value);
-}
-
-Status
-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)) {
- Status 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 Status("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);
-}
-
-Status NativeRegisterContextLinux::ReadGPR() {
- void *buf = GetGPRBuffer();
- if (!buf)
- return Status("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
-
- return DoReadGPR(buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::WriteGPR() {
- void *buf = GetGPRBuffer();
- if (!buf)
- return Status("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
-
- return DoWriteGPR(buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::ReadFPR() {
- void *buf = GetFPRBuffer();
- if (!buf)
- return Status("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
-
- return DoReadFPR(buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::WriteFPR() {
- void *buf = GetFPRBuffer();
- if (!buf)
- return Status("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
-
- return DoWriteFPR(buf, buf_size);
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset,
- const char *reg_name,
- uint32_t size,
- RegisterValue &value) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
-
- long data;
- Status 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);
-
- LLDB_LOG(log, "{0}: {1:x}", reg_name, data);
- return error;
-}
-
-Status 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());
- LLDB_LOG(log, "{0}: {1}", reg_name, buf);
-
- return NativeProcessLinux::PtraceWrapper(
- PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
-}
-
-Status NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-}
-
-Status 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
deleted file mode 100644
index 2cea497b53bcd..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- NativeRegisterContextLinux.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_NativeRegisterContextLinux_h
-#define lldb_NativeRegisterContextLinux_h
-
-#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
-public:
- NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- 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 std::unique_ptr<NativeRegisterContextLinux>
- CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
-protected:
- lldb::ByteOrder GetByteOrder() const;
-
- virtual Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value);
-
- virtual Status WriteRegisterRaw(uint32_t reg_index,
- const RegisterValue &reg_value);
-
- virtual Status ReadRegisterSet(void *buf, size_t buf_size,
- unsigned int regset);
-
- virtual Status WriteRegisterSet(void *buf, size_t buf_size,
- unsigned int regset);
-
- virtual Status ReadGPR();
-
- virtual Status WriteGPR();
-
- virtual Status ReadFPR();
-
- virtual Status WriteFPR();
-
- virtual void *GetGPRBuffer() { return nullptr; }
-
- virtual size_t GetGPRSize() {
- return GetRegisterInfoInterface().GetGPRSize();
- }
-
- virtual void *GetFPRBuffer() { return nullptr; }
-
- virtual size_t GetFPRSize() { return 0; }
-
- // The Do*** functions are executed on the privileged thread and can perform
- // ptrace
- // operations directly.
- virtual Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value);
-
- virtual Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value);
-
- virtual Status DoReadGPR(void *buf, size_t buf_size);
-
- virtual Status DoWriteGPR(void *buf, size_t buf_size);
-
- virtual Status DoReadFPR(void *buf, size_t buf_size);
-
- virtual Status DoWriteFPR(void *buf, size_t buf_size);
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_h
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
deleted file mode 100644
index 09d3a12942f05..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ /dev/null
@@ -1,975 +0,0 @@
-//===-- NativeRegisterContextLinux_arm.cpp --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-
-#include "NativeRegisterContextLinux_arm.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include <elf.h>
-#include <sys/socket.h>
-
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(m_fpr))
-
-#ifndef PTRACE_GETVFPREGS
-#define PTRACE_GETVFPREGS 27
-#define PTRACE_SETVFPREGS 28
-#endif
-#ifndef PTRACE_GETHBPREGS
-#define PTRACE_GETHBPREGS 29
-#define PTRACE_SETHBPREGS 30
-#endif
-#if !defined(PTRACE_TYPE_ARG3)
-#define PTRACE_TYPE_ARG3 void *
-#endif
-#if !defined(PTRACE_TYPE_ARG4)
-#define PTRACE_TYPE_ARG4 void *
-#endif
-
-using namespace lldb;
-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,
- 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,
- "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,
- 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,
- "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 };
-}
-
-// 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}};
-
-#if defined(__arm__)
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
- native_thread);
-}
-
-#endif // defined(__arm__)
-
-NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- new RegisterInfoPOSIX_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));
- ::memset(&m_hbr_regs, 0, sizeof(m_hbr_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;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_arm::GetRegisterSet(uint32_t set_index) const {
- if (set_index < k_num_register_sets)
- return &g_reg_sets_arm[set_index];
-
- return nullptr;
-}
-
-Status
-NativeRegisterContextLinux_arm::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- 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;
- }
-
- // 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;
-}
-
-Status
-NativeRegisterContextLinux_arm::WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("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 Status("unhandled register data size %" PRIu32,
- reg_info->byte_size);
- }
-
- Status error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- return Status("failed - register wasn't recognized to be a GPR or an FPR, "
- "write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_arm::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
- (uint64_t)REG_CONTEXT_SIZE);
-
- error = ReadGPR();
- 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",
- (uint64_t)REG_CONTEXT_SIZE);
- return error;
- }
-
- ::memcpy(dst, &m_gpr_arm, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr, sizeof(m_fpr));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_arm::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
- __FUNCTION__);
- 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());
-
- 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_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);
-}
-
-uint32_t NativeRegisterContextLinux_arm::NumSupportedHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", m_max_hbp_supported);
- return m_max_hbp_supported;
-}
-
-uint32_t
-NativeRegisterContextLinux_arm::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, bp_index = 0;
-
- // Setup address and control values.
- // Use size to get a hint of arm vs thumb modes.
- switch (size) {
- case 2:
- control_value = (0x3 << 5) | 7;
- addr &= ~1;
- break;
- case 4:
- control_value = (0xfu << 5) | 7;
- addr &= ~3;
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
-
- // Iterate over stored breakpoints and find a free bp_index
- 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) {
- return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
- }
- }
-
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Update breakpoint in local cache
- m_hbr_regs[bp_index].real_addr = addr;
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
-
- // 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;
-
- return LLDB_INVALID_INDEX32;
- }
-
- return bp_index;
-}
-
-bool NativeRegisterContextLinux_arm::ClearHardwareBreakpoint(uint32_t hw_idx) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "hw_idx: {0}", hw_idx);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (hw_idx >= m_max_hbp_supported)
- return false;
-
- // 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;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
-
- if (error.Fail()) {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
-
- return false;
- }
-
- return true;
-}
-
-Status NativeRegisterContextLinux_arm::GetHardwareBreakHitIndex(
- uint32_t &bp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- lldb::addr_t break_addr;
-
- for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
- break_addr = m_hbr_regs[bp_index].address;
-
- if ((m_hbr_regs[bp_index].control & 0x1) && (trap_addr == break_addr)) {
- m_hbr_regs[bp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- bp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-Status NativeRegisterContextLinux_arm::ClearAllHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0;
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- if (m_hbr_regs[i].control & 0x01) {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hbr_regs[i].address;
- tempControl = m_hbr_regs[i].control;
-
- // Clear breakpoints in local cache
- m_hbr_regs[i].control &= ~1;
- m_hbr_regs[i].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, i);
-
- if (error.Fail()) {
- m_hbr_regs[i].control = tempControl;
- m_hbr_regs[i].address = tempAddr;
-
- return error;
- }
- }
- }
-
- return Status();
-}
-
-uint32_t NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", 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(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
- watch_flags);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- 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;
- }
-
- // Can't watch zero bytes
- // Can't watch more than 4 bytes per WVR/WCR pair
-
- if (size == 0 || size > 4)
- return LLDB_INVALID_INDEX32;
-
- // 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 (watch_mask > 0x04)
- return LLDB_INVALID_INDEX32;
- else if (watch_mask <= 0x02)
- size = 2;
- else if (watch_mask <= 0x04)
- size = 4;
-
- addr = addr & (~0x03);
- }
-
- // 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 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, 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;
-}
-
-bool NativeRegisterContextLinux_arm::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (wp_index >= m_max_hwp_supported)
- return false;
-
- // 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, wp_index);
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
-
- return false;
- }
-
- return true;
-}
-
-Status NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints() {
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 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, i);
-
- if (error.Fail()) {
- m_hwp_regs[i].control = tempControl;
- m_hwp_regs[i].address = tempAddr;
-
- return error;
- }
- }
- }
-
- return Status();
-}
-
-uint32_t NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- 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(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
-}
-
-Status
-NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
-
- 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 (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
- trap_addr < watch_addr + watch_size) {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- 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;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointHitAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- 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;
-}
-
-Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() {
- Status error;
-
- if (!m_refresh_hwdebug_info) {
- return Status();
- }
-
- unsigned int cap_val;
-
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(),
- nullptr, &cap_val,
- 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;
-}
-
-Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType,
- int hwb_index) {
- Status 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));
-
- if (error.Fail())
- 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_hbr_regs[hwb_index].address;
- ctrl_buf = &m_hbr_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));
-
- if (error.Fail())
- 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;
-}
-
-Status 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 Status("Register isn't fit into the size of the GPR area");
-
- Status error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
- if (error.Fail())
- return error;
-
- value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
- return Status();
-}
-
-Status 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 Status("Register isn't fit into the size of the GPR area");
-
- Status 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);
- }
- }
-
- m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
- return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
-}
-
-Status 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 ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
-#endif // __arm__
-}
-
-Status 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 WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
-#endif // __arm__
-}
-
-Status 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);
-#endif // __arm__
-}
-
-Status 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);
-#endif // __arm__
-}
-
-#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
deleted file mode 100644
index d0b068550a9ee..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- NativeRegisterContextLinux_arm.h ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-
-#ifndef lldb_NativeRegisterContextLinux_arm_h
-#define lldb_NativeRegisterContextLinux_arm_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/lldb-arm-register-enums.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_arm(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint management functions
- //------------------------------------------------------------------
-
- uint32_t NumSupportedHardwareBreakpoints() override;
-
- uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
- Status ClearAllHardwareBreakpoints() override;
-
- Status GetHardwareBreakHitIndex(uint32_t &bp_index,
- lldb::addr_t trap_addr) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t GetWatchpointSize(uint32_t wp_index);
-
- bool WatchpointIsEnabled(uint32_t wp_index);
-
- // Debug register type select
- enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
-
-protected:
- Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value) override;
-
- Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value) override;
-
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status DoWriteFPR(void *buf, size_t buf_size) override;
-
- void *GetGPRBuffer() override { return &m_gpr_arm; }
-
- void *GetFPRBuffer() override { return &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;
-
- 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[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 reference counter.
- };
-
- 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;
-
- bool IsGPR(unsigned reg) const;
-
- bool IsFPR(unsigned reg) const;
-
- Status ReadHardwareDebugInfo();
-
- Status WriteHardwareDebugRegs(int hwbType, int hwb_index);
-
- uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_arm_h
-
-#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
deleted file mode 100644
index 9a392edbe9ef3..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ /dev/null
@@ -1,985 +0,0 @@
-//===-- NativeRegisterContextLinux_arm64.cpp --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm64__) || defined(__aarch64__)
-
-#include "NativeRegisterContextLinux_arm.h"
-#include "NativeRegisterContextLinux_arm64.h"
-
-
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
-
-// 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
-#include <elf.h>
-// user_hwdebug_state definition
-#include <asm/ptrace.h>
-
-#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
-
-using namespace lldb;
-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, 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,
- "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_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,
- "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 };
-}
-
-// 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}};
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::arm:
- return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
- native_thread);
- case llvm::Triple::aarch64:
- return llvm::make_unique<NativeRegisterContextLinux_arm64>(target_arch,
- native_thread);
- default:
- llvm_unreachable("have no register context for architecture");
- }
-}
-
-NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- 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:
- llvm_unreachable("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));
- ::memset(&m_hbr_regs, 0, sizeof(m_hbr_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;
-}
-
-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;
-}
-
-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;
-}
-
-Status
-NativeRegisterContextLinux_arm64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- 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;
- }
-
- // 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;
-}
-
-Status NativeRegisterContextLinux_arm64::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("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 Status("unhandled register data size %" PRIu32,
- reg_info->byte_size);
- }
-
- Status error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- return Status("failed - register wasn't recognized to be a GPR or an FPR, "
- "write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
- REG_CONTEXT_SIZE);
-
- error = ReadGPR();
- 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;
- }
-
- ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr, sizeof(m_fpr));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
- __FUNCTION__);
- 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;
- }
-
- 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 = 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::IsFPR(unsigned reg) const {
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
-}
-
-uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- return m_max_hbp_supported;
-}
-
-uint32_t
-NativeRegisterContextLinux_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
-
- // Read hardware breakpoint and watchpoint information.
- Status 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 breakpoints and find a free bp_index
- 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) {
- return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
- }
- }
-
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Update breakpoint in local cache
- m_hbr_regs[bp_index].real_addr = addr;
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
-
- // 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;
-
- return LLDB_INVALID_INDEX32;
- }
-
- return bp_index;
-}
-
-bool NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint(
- uint32_t hw_idx) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "hw_idx: {0}", hw_idx);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (hw_idx >= m_max_hbp_supported)
- return false;
-
- // 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;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
- if (error.Fail()) {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
-
- return false;
- }
-
- return true;
-}
-
-Status NativeRegisterContextLinux_arm64::GetHardwareBreakHitIndex(
- uint32_t &bp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- lldb::addr_t break_addr;
-
- for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
- break_addr = m_hbr_regs[bp_index].address;
-
- if ((m_hbr_regs[bp_index].control & 0x1) && (trap_addr == break_addr)) {
- m_hbr_regs[bp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- bp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-Status NativeRegisterContextLinux_arm64::ClearAllHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0;
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- if (m_hbr_regs[i].control & 0x01) {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hbr_regs[i].address;
- tempControl = m_hbr_regs[i].control;
-
- // Clear watchpoints in local cache
- m_hbr_regs[i].control &= ~1;
- m_hbr_regs[i].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
- if (error.Fail()) {
- m_hbr_regs[i].control = tempControl;
- m_hbr_regs[i].address = tempAddr;
-
- return error;
- }
- }
- }
-
- return Status();
-}
-
-uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", 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(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
- watch_flags);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- 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;
- }
-
- // 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);
- }
-
- // 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 LLDB_INVALID_INDEX32;
- }
-
- return wp_index;
-}
-
-bool NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (wp_index >= m_max_hwp_supported)
- return false;
-
- // 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;
-}
-
-Status NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints() {
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 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 Status();
-}
-
-uint32_t
-NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- 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(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
-}
-
-Status NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
-
- 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 (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
- trap_addr < watch_addr + watch_size) {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- 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;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- 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;
-}
-
-Status NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
- if (!m_refresh_hwdebug_info) {
- return Status();
- }
-
- ::pid_t tid = m_thread.GetID();
-
- int regset = NT_ARM_HW_WATCH;
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Status error;
-
- ioVec.iov_base = &dreg_state;
- ioVec.iov_len = sizeof(dreg_state);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
- &ioVec, ioVec.iov_len);
-
- if (error.Fail())
- return error;
-
- m_max_hwp_supported = dreg_state.dbg_info & 0xff;
-
- 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;
-}
-
-Status NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType) {
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Status 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;
- }
- }
-
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- &hwbType, &ioVec, ioVec.iov_len);
-}
-
-Status NativeRegisterContextLinux_arm64::DoReadRegisterValue(
- uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value) {
- Status error;
- if (offset > sizeof(struct user_pt_regs)) {
- 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()) {
- value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
- m_thread.GetProcess().GetByteOrder());
- }
- } 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()) {
- value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
- m_thread.GetProcess().GetByteOrder());
- }
- }
- return error;
-}
-
-Status NativeRegisterContextLinux_arm64::DoWriteRegisterValue(
- uint32_t offset, const char *reg_name, const RegisterValue &value) {
- Status error;
- ::pid_t tid = m_thread.GetID();
- if (offset > sizeof(struct user_pt_regs)) {
- 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);
- }
- } 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;
-}
-
-Status NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) {
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
- Status error;
-
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
- &regset, &ioVec, buf_size);
-}
-
-Status NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf,
- size_t buf_size) {
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
- Status error;
-
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- &regset, &ioVec, buf_size);
-}
-
-Status NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) {
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Status error;
-
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
- &regset, &ioVec, buf_size);
-}
-
-Status NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf,
- size_t buf_size) {
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Status 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
deleted file mode 100644
index c859d4249d053..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- NativeRegisterContextLinux_arm64.h ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm64__) || defined(__aarch64__)
-
-#ifndef lldb_NativeRegisterContextLinux_arm64_h
-#define lldb_NativeRegisterContextLinux_arm64_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint management functions
- //------------------------------------------------------------------
-
- uint32_t NumSupportedHardwareBreakpoints() override;
-
- uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
- Status ClearAllHardwareBreakpoints() override;
-
- Status GetHardwareBreakHitIndex(uint32_t &bp_index,
- lldb::addr_t trap_addr) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t GetWatchpointSize(uint32_t wp_index);
-
- bool WatchpointIsEnabled(uint32_t wp_index);
-
- // Debug register type select
- enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
-
-protected:
- Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value) override;
-
- Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value) override;
-
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status DoWriteFPR(void *buf, size_t buf_size) override;
-
- void *GetGPRBuffer() override { return &m_gpr_arm64; }
-
- void *GetFPRBuffer() override { return &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;
-
- 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[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 reference counter.
- };
-
- 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;
-
- bool IsGPR(unsigned reg) const;
-
- bool IsFPR(unsigned reg) const;
-
- Status ReadHardwareDebugInfo();
-
- Status WriteHardwareDebugRegs(int hwbType);
-
- uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_arm64_h
-
-#endif // defined (__arm64__) || defined (__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
deleted file mode 100644
index d641056a04401..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ /dev/null
@@ -1,1053 +0,0 @@
-//===-- NativeRegisterContextLinux_mips64.cpp ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__mips__)
-
-#include "NativeRegisterContextLinux_mips64.h"
-
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "lldb/Core/EmulateInstruction.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-private-enumerations.h"
-#define NT_MIPS_MSA 0x600
-#define CONFIG5_FRE (1 << 8)
-#define SR_FR (1 << 26)
-#define NUM_REGISTERS 32
-
-#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;
-} __attribute__((aligned(8)));
-
-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;
- };
-};
-
-#define PTRACE_GET_WATCH_REGS 0xd0
-#define PTRACE_SET_WATCH_REGS 0xd1
-#endif
-
-#define W (1 << 0)
-#define R (1 << 1)
-#define I (1 << 2)
-
-#define IRW (I | R | W)
-
-#ifndef PTRACE_GETREGSET
-#define PTRACE_GETREGSET 0x4204
-#endif
-struct pt_watch_regs default_watch_regs;
-
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return llvm::make_unique<NativeRegisterContextLinux_mips64>(target_arch,
- native_thread);
-}
-
-#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 ((target_arch.GetMachine() == llvm::Triple::mips) ||
- (target_arch.GetMachine() == llvm::Triple::mipsel)) {
- // 32-bit hosts run with a RegisterContextLinux_mips context.
- return new RegisterContextLinux_mips(
- target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- } else {
- return new RegisterContextLinux_mips64(
- target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- }
-}
-
-NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- 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));
-}
-
-uint32_t NativeRegisterContextLinux_mips64::GetRegisterSetCount() const {
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el: {
- const auto context = static_cast<const RegisterContextLinux_mips64 &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSetCount();
- }
- case llvm::Triple::mips:
- case llvm::Triple::mipsel: {
- const auto context = static_cast<const RegisterContextLinux_mips &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSetCount();
- }
- default:
- llvm_unreachable("Unhandled target architecture.");
- }
-}
-
-lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
- lldb::addr_t fail_value) {
- Status error;
- RegisterValue pc_value;
- lldb::addr_t pc = fail_value;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "Reading PC from breakpoint location");
-
- // 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_LOG(log, "PC {0:x} cause {1:x}", 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);
- LLDB_LOG(log, "New PC {0:x}", pc);
- }
- }
-
- return pc;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const {
- if (set_index >= GetRegisterSetCount())
- return nullptr;
-
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el: {
- const auto context = static_cast<const RegisterContextLinux_mips64 &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSet(set_index);
- }
- case llvm::Triple::mips:
- case llvm::Triple::mipsel: {
- const auto context = static_cast<const RegisterContextLinux_mips &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSet(set_index);
- }
- default:
- llvm_unreachable("Unhandled target architecture.");
- }
-}
-
-lldb_private::Status
-NativeRegisterContextLinux_mips64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status 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) && !IsMSAAvailable()) {
- error.SetErrorString("MSA not available on this processor");
- return error;
- }
-
- if (IsMSA(reg) || IsFPR(reg)) {
- uint8_t *src = nullptr;
- lldbassert(reg_info->byte_offset < sizeof(UserArea));
-
- error = ReadCP1();
-
- if (!error.Success()) {
- error.SetErrorString("failed to read co-processor 1 register");
- return error;
- }
-
- 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;
-}
-
-lldb_private::Status NativeRegisterContextLinux_mips64::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- Status error;
-
- assert(reg_info && "reg_info is null");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("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 (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;
- }
- } else {
- error = WriteRegisterRaw(reg_index, reg_value);
- }
-
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status 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 = 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;
- }
-
- ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
- dst += GetRegisterInfoInterface().GetGPRSize();
-
- ::memcpy(dst, &m_fpr, GetFPRSize());
- dst += GetFPRSize();
-
- ::memcpy(dst, &m_msa, sizeof(MSA_linux_mips));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status 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;
- }
-
- 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();
-
- ::memcpy(&m_fpr, src, GetFPRSize());
- src += GetFPRSize();
-
- ::memcpy(&m_msa, src, sizeof(MSA_linux_mips));
-
- error = WriteGPR();
- if (!error.Success()) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_mips64::%s WriteGPR() failed",
- __FUNCTION__);
- return error;
- }
-
- error = WriteCP1();
- if (!error.Success()) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_mips64::%s WriteCP1() failed",
- __FUNCTION__);
- return error;
- }
-
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::ReadCP1() {
- Status error;
-
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
-
- 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();
- }
- 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;
-}
-
-Status NativeRegisterContextLinux_mips64::WriteCP1() {
- Status error;
-
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
-
- lldb::ByteOrder byte_order = GetByteOrder();
-
- 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();
- }
-
- return error;
-}
-
-bool NativeRegisterContextLinux_mips64::IsFR0() {
- const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex(gpr_sr_mips64);
-
- RegisterValue reg_value;
- ReadRegister(reg_info_p, reg_value);
-
- uint64_t value = reg_value.GetAsUInt64();
-
- return (!(value & SR_FR));
-}
-
-bool NativeRegisterContextLinux_mips64::IsFRE() {
- const RegisterInfo *const reg_info_p =
- GetRegisterInfoAtIndex(gpr_config5_mips64);
-
- RegisterValue reg_value;
- ReadRegister(reg_info_p, reg_value);
-
- uint64_t config5 = reg_value.GetAsUInt64();
-
- 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);
-}
-
-static uint32_t GetWatchHi(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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];
- LLDB_LOG(log, "Invalid watch register style");
- return 0;
-}
-
-static void SetWatchHi(struct pt_watch_regs *regs, uint32_t index,
- uint16_t value) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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;
- LLDB_LOG(log, "Invalid watch register style");
- return;
-}
-
-static lldb::addr_t GetWatchLo(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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];
- LLDB_LOG(log, "Invalid watch register style");
- return LLDB_INVALID_ADDRESS;
-}
-
-static void SetWatchLo(struct pt_watch_regs *regs, uint32_t index,
- uint64_t value) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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;
- else
- LLDB_LOG(log, "Invalid watch register style");
-}
-
-static uint32_t GetIRWMask(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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;
- LLDB_LOG(log, "Invalid watch register style");
- return 0;
-}
-
-static uint32_t GetRegMask(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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;
- LLDB_LOG(log, "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 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++;
- }
- }
- }
-
- 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;
-}
-
-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;
-
- Status 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;
- }
-
- return false;
-}
-
-Status NativeRegisterContextLinux_mips64::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- // reading the current state of watch regs
- struct pt_watch_regs watch_readback;
- Status 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;
-}
-
-Status 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;
- Status 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 Status();
-}
-
-Status NativeRegisterContextLinux_mips64::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- is_vacant = false;
- return Status("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];
- }
-
- Status error = DoWriteWatchPointRegisterValue(m_thread.GetID(),
- static_cast<void *>(&regs));
- if (!error.Fail()) {
- hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
- return true;
- }
- return false;
-}
-
-Status NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints() {
- return DoWriteWatchPointRegisterValue(
- m_thread.GetID(), static_cast<void *>(&default_watch_regs));
-}
-
-Status NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
- Status 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;
-
- // 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());
-
- // 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));
-
- // 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;
-
- 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) {}
-};
-
-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 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]);
-
- Status error =
- emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
-
- 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();
- }
-
- return true;
-}
-
-/*
- * MIPS Linux kernel returns a masked address (last 3bits are masked)
- * when a HW watchpoint is hit. However user may not have set a watchpoint
- * on this address. Emulate instruction at PC and find the base address of
- * the load/store instruction. This will give the exact address used to
- * read/write the variable. Send this exact address to client so that
- * 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;
-
- 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()), 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(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_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;
- }
- LLDB_LOG(log, "Invalid watch register style");
- return 0;
- }
- return num_valid;
-}
-
-Status
-NativeRegisterContextLinux_mips64::ReadRegisterRaw(uint32_t reg_index,
- RegisterValue &value) {
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
-
- if (!reg_info)
- return Status("register %" PRIu32 " not found", reg_index);
-
- 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);
-
- return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
- value);
-}
-
-Status NativeRegisterContextLinux_mips64::WriteRegisterRaw(
- uint32_t reg_index, const RegisterValue &value) {
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
-
- if (!reg_info)
- return Status("register %" PRIu32 " not found", reg_index);
-
- 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);
-}
-
-Status 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));
-
- Status error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
- if (error.Success()) {
- const lldb_private::ArchSpec &arch =
- m_thread.GetProcess().GetArchitecture();
- void *target_address = ((uint8_t *)&regs) + offset +
- 4 * (arch.GetMachine() == llvm::Triple::mips);
- value.SetUInt(*(uint32_t *)target_address, size);
- }
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(
- lldb::tid_t tid, void *watch_readback) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_GET_WATCH_REGS,
- m_thread.GetID(), watch_readback);
-}
-
-Status 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
deleted file mode 100644
index c4e984a545bc6..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- NativeRegisterContextLinux_mips64.h ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__mips__)
-
-#ifndef lldb_NativeRegisterContextLinux_mips64_h
-#define lldb_NativeRegisterContextLinux_mips64_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/RegisterContext_mips.h"
-#include "Plugins/Process/Utility/lldb-mips-linux-register-enums.h"
-#include <sys/uio.h>
-
-#define MAX_NUM_WP 8
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_mips64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- lldb::addr_t GetPCfromBreakpointLocation(
- lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- Status ReadCP1();
-
- Status WriteCP1();
-
- uint8_t *ReturnFPOffset(uint8_t reg_index, uint32_t byte_offset);
-
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status 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;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- static bool IsMSAAvailable();
-
-protected:
- Status Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value);
-
- Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
-
- Status WriteRegisterRaw(uint32_t reg_index,
- const RegisterValue &value) override;
-
- Status DoReadWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
-
- Status DoWriteWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
-
- bool IsFR0();
-
- bool IsFRE();
-
- bool IsFPR(uint32_t reg_index) const;
-
- bool IsMSA(uint32_t reg_index) const;
-
- void *GetGPRBuffer() override { return &m_gpr; }
-
- void *GetFPRBuffer() override { return &m_fpr; }
-
- 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;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- uint32_t first_msa;
- uint32_t last_msa;
- };
-
- RegInfo m_reg_info;
-
- GPR_linux_mips m_gpr;
-
- FPR_linux_mips m_fpr;
-
- MSA_linux_mips m_msa;
-
- lldb::addr_t hw_addr_map[MAX_NUM_WP];
-
- struct iovec m_iovec;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_mips64_h
-
-#endif // defined (__mips__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
deleted file mode 100644
index da51fda1c80b3..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
+++ /dev/null
@@ -1,804 +0,0 @@
-//===-- NativeRegisterContextLinux_ppc64le.cpp ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This implementation is related to the OpenPOWER ABI for Power Architecture
-// 64-bit ELF V2 ABI
-
-#if defined(__powerpc64__)
-
-#include "NativeRegisterContextLinux_ppc64le.h"
-
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
-
-// 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>
-#include <elf.h>
-#include <asm/ptrace.h>
-
-#define REG_CONTEXT_SIZE \
- (GetGPRSize() + GetFPRSize() + sizeof(m_vmx_ppc64le) + sizeof(m_vsx_ppc64le))
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-static const uint32_t g_gpr_regnums_ppc64le[] = {
- gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le,
- gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le,
- gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le,
- gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le,
- gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le,
- gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le,
- gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le,
- gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_ppc64le,
- gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le,
- gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le,
- gpr_trap_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static const uint32_t g_fpr_regnums_ppc64le[] = {
- fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le,
- fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le,
- fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le,
- fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le,
- fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le,
- fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_ppc64le,
- fpr_f24_ppc64le, fpr_f25_ppc64le, fpr_f26_ppc64le, fpr_f27_ppc64le,
- fpr_f28_ppc64le, fpr_f29_ppc64le, fpr_f30_ppc64le, fpr_f31_ppc64le,
- fpr_fpscr_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static const uint32_t g_vmx_regnums_ppc64le[] = {
- vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le,
- vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le,
- vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le,
- vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le,
- vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le,
- vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_ppc64le,
- vmx_vr24_ppc64le, vmx_vr25_ppc64le, vmx_vr26_ppc64le, vmx_vr27_ppc64le,
- vmx_vr28_ppc64le, vmx_vr29_ppc64le, vmx_vr30_ppc64le, vmx_vr31_ppc64le,
- vmx_vscr_ppc64le, vmx_vrsave_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static const uint32_t g_vsx_regnums_ppc64le[] = {
- vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le,
- vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le,
- vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le,
- vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le,
- vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le,
- vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le,
- vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le,
- vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le,
- vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le,
- vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le,
- vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le,
- vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le,
- vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_ppc64le,
- vsx_vs52_ppc64le, vsx_vs53_ppc64le, vsx_vs54_ppc64le, vsx_vs55_ppc64le,
- vsx_vs56_ppc64le, vsx_vs57_ppc64le, vsx_vs58_ppc64le, vsx_vs59_ppc64le,
- vsx_vs60_ppc64le, vsx_vs61_ppc64le, vsx_vs62_ppc64le, vsx_vs63_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-namespace {
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 4 };
-}
-
-static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le,
- g_gpr_regnums_ppc64le},
- {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le,
- g_fpr_regnums_ppc64le},
- {"AltiVec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le,
- g_vmx_regnums_ppc64le},
- {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le,
- g_vsx_regnums_ppc64le},
-};
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::ppc64le:
- return llvm::make_unique<NativeRegisterContextLinux_ppc64le>(target_arch,
- native_thread);
- default:
- llvm_unreachable("have no register context for architecture");
- }
-}
-
-NativeRegisterContextLinux_ppc64le::NativeRegisterContextLinux_ppc64le(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- new RegisterInfoPOSIX_ppc64le(target_arch)) {
- if (target_arch.GetMachine() != llvm::Triple::ppc64le) {
- llvm_unreachable("Unhandled target architecture.");
- }
-
- ::memset(&m_gpr_ppc64le, 0, sizeof(m_gpr_ppc64le));
- ::memset(&m_fpr_ppc64le, 0, sizeof(m_fpr_ppc64le));
- ::memset(&m_vmx_ppc64le, 0, sizeof(m_vmx_ppc64le));
- ::memset(&m_vsx_ppc64le, 0, sizeof(m_vsx_ppc64le));
- ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::GetRegisterSetCount() const {
- return k_num_register_sets;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_ppc64le::GetRegisterSet(uint32_t set_index) const {
- if (set_index < k_num_register_sets)
- return &g_reg_sets_ppc64le[set_index];
-
- return nullptr;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::GetUserRegisterCount() const {
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_ppc64le[set_index].num_registers;
- return count;
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadRegister(
- const RegisterInfo *reg_info, RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- // Get pointer to m_fpr_ppc64le variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < sizeof m_fpr_ppc64le);
- uint8_t *src = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- } else if (IsVSX(reg)) {
- uint32_t vsx_offset = CalculateVsxOffset(reg_info);
- assert(vsx_offset < sizeof(m_vsx_ppc64le));
-
- if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
- error = ReadVSX();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint64_t value[2];
- uint8_t *dst, *src;
- dst = (uint8_t *)&value;
- src = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
- dst += 8;
- src = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
- reg_value.SetFromMemoryData(reg_info, &value, reg_info->byte_size,
- eByteOrderLittle, error);
- } else {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data from it.
- uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
- uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- }
- } else if (IsVMX(reg)) {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data from it.
- uint32_t vmx_offset = CalculateVmxOffset(reg_info);
- assert(vmx_offset < sizeof m_vmx_ppc64le);
- uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- } else if (IsGPR(reg)) {
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- uint8_t *src = (uint8_t *) &m_gpr_ppc64le + reg_info->byte_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- } else {
- return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
- "or VMX, read strategy unknown");
- }
-
- return error;
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- Status error;
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("no lldb regnum for %s", reg_info && reg_info->name
- ? reg_info->name
- : "<unknown register>");
-
- if (IsGPR(reg_index)) {
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- uint8_t *dst = (uint8_t *)&m_gpr_ppc64le + reg_info->byte_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
-
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- if (IsFPR(reg_index)) {
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- // Get pointer to m_fpr_ppc64le variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < GetFPRSize());
- uint8_t *dst = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- if (IsVMX(reg_index)) {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data to it.
- uint32_t vmx_offset = CalculateVmxOffset(reg_info);
- assert(vmx_offset < sizeof(m_vmx_ppc64le));
- uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
-
- error = WriteVMX();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- if (IsVSX(reg_index)) {
- uint32_t vsx_offset = CalculateVsxOffset(reg_info);
- assert(vsx_offset < sizeof(m_vsx_ppc64le));
-
- if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
- error = ReadVSX();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint64_t value[2];
- ::memcpy(value, reg_value.GetBytes(), 16);
- uint8_t *dst, *src;
- src = (uint8_t *)value;
- dst = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
- src += 8;
- dst = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
-
- WriteVSX();
- WriteFPR();
- } else {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data from it.
- uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
- uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
- WriteVMX();
- }
-
- return Status();
- }
-
- return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
- "or VMX, write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
- REG_CONTEXT_SIZE);
-
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- error = ReadVSX();
- 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;
- }
-
- ::memcpy(dst, &m_gpr_ppc64le, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr_ppc64le, GetFPRSize());
- dst += GetFPRSize();
- ::memcpy(dst, &m_vmx_ppc64le, sizeof(m_vmx_ppc64le));
- dst += sizeof(m_vmx_ppc64le);
- ::memcpy(dst, &m_vsx_ppc64le, sizeof(m_vsx_ppc64le));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_ppc64le::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_ppc64le::%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_ppc64le::%s "
- "DataBuffer::GetBytes() returned a null "
- "pointer",
- __FUNCTION__);
- return error;
- }
-
- ::memcpy(&m_gpr_ppc64le, src, GetGPRSize());
- error = WriteGPR();
-
- if (error.Fail())
- return error;
-
- src += GetGPRSize();
- ::memcpy(&m_fpr_ppc64le, src, GetFPRSize());
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- src += GetFPRSize();
- ::memcpy(&m_vmx_ppc64le, src, sizeof(m_vmx_ppc64le));
-
- error = WriteVMX();
- if (error.Fail())
- return error;
-
- src += sizeof(m_vmx_ppc64le);
- ::memcpy(&m_vsx_ppc64le, src, sizeof(m_vsx_ppc64le));
- error = WriteVSX();
-
- return error;
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsGPR(unsigned reg) const {
- return reg <= k_last_gpr_ppc64le; // GPR's come first.
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsFPR(unsigned reg) const {
- return (k_first_fpr_ppc64le <= reg && reg <= k_last_fpr_ppc64le);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoReadGPR(
- void *buf, size_t buf_size) {
- int regset = NT_PRSTATUS;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoWriteGPR(
- void *buf, size_t buf_size) {
- int regset = NT_PRSTATUS;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoReadFPR(void *buf,
- size_t buf_size) {
- int regset = NT_FPREGSET;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoWriteFPR(void *buf,
- size_t buf_size) {
- int regset = NT_FPREGSET;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::CalculateFprOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(k_first_fpr_ppc64le)->byte_offset;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::CalculateVmxOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(k_first_vmx_ppc64le)->byte_offset;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::CalculateVsxOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(k_first_vsx_ppc64le)->byte_offset;
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadVMX() {
- int regset = NT_PPC_VMX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETVRREGS, m_thread.GetID(),
- &regset, &m_vmx_ppc64le,
- sizeof(m_vmx_ppc64le));
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteVMX() {
- int regset = NT_PPC_VMX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETVRREGS, m_thread.GetID(),
- &regset, &m_vmx_ppc64le,
- sizeof(m_vmx_ppc64le));
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadVSX() {
- int regset = NT_PPC_VSX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETVSRREGS, m_thread.GetID(),
- &regset, &m_vsx_ppc64le,
- sizeof(m_vsx_ppc64le));
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteVSX() {
- int regset = NT_PPC_VSX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETVSRREGS, m_thread.GetID(),
- &regset, &m_vsx_ppc64le,
- sizeof(m_vsx_ppc64le));
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsVMX(unsigned reg) {
- return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le);
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsVSX(unsigned reg) {
- return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le);
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::NumSupportedHardwareWatchpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", m_max_hwp_supported);
- return m_max_hwp_supported;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
- watch_flags);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0;
- lldb::addr_t real_addr = addr;
- uint32_t rw_mode = 0;
-
- // Check if we are setting watchpoint other than read/write/access Update
- // watchpoint flag to match ppc64le write-read bit configuration.
- switch (watch_flags) {
- case eWatchpointKindWrite:
- rw_mode = PPC_BREAKPOINT_TRIGGER_WRITE;
- watch_flags = 2;
- break;
- case eWatchpointKindRead:
- rw_mode = PPC_BREAKPOINT_TRIGGER_READ;
- watch_flags = 1;
- break;
- case (eWatchpointKindRead | eWatchpointKindWrite):
- rw_mode = PPC_BREAKPOINT_TRIGGER_RW;
- 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) {
-
- addr_t begin = llvm::alignDown(addr, 8);
- addr_t end = llvm::alignTo(addr + size, 8);
- size = llvm::PowerOf2Ceil(end - begin);
-
- 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;
- m_hwp_regs[wp_index].mode = rw_mode;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs();
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
-
- return LLDB_INVALID_INDEX32;
- }
-
- return wp_index;
-}
-
-bool NativeRegisterContextLinux_ppc64le::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (wp_index >= m_max_hwp_supported)
- return false;
-
- // 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;
- long *tempSlot = reinterpret_cast<long *>(m_hwp_regs[wp_index].slot);
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].slot = 0;
- m_hwp_regs[wp_index].mode = 0;
-
- // Ptrace call to update hardware debug registers
- error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_DELHWDEBUG,
- m_thread.GetID(), 0, tempSlot);
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
- m_hwp_regs[wp_index].slot = reinterpret_cast<long>(tempSlot);
-
- return false;
- }
-
- return true;
-}
-
-uint32_t
-NativeRegisterContextLinux_ppc64le::GetWatchpointSize(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- unsigned control = (m_hwp_regs[wp_index].control >> 5) & 0xff;
- if (llvm::isPowerOf2_32(control + 1)) {
- return llvm::countPopulation(control);
- }
-
- return 0;
-}
-
-bool NativeRegisterContextLinux_ppc64le::WatchpointIsEnabled(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- return !!((m_hwp_regs[wp_index].control & 0x1) == 0x1);
-}
-
-Status NativeRegisterContextLinux_ppc64le::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
-
- 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 (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
- trap_addr <= watch_addr + watch_size) {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_ppc64le::GetWatchpointAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- 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;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_ppc64le::GetWatchpointHitAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
-
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
-
- return LLDB_INVALID_ADDRESS;
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadHardwareDebugInfo() {
- if (!m_refresh_hwdebug_info) {
- return Status();
- }
-
- ::pid_t tid = m_thread.GetID();
-
- struct ppc_debug_info hwdebug_info;
- Status error;
-
- error = NativeProcessLinux::PtraceWrapper(
- PPC_PTRACE_GETHWDBGINFO, tid, 0, &hwdebug_info, sizeof(hwdebug_info));
-
- if (error.Fail())
- return error;
-
- m_max_hwp_supported = hwdebug_info.num_data_bps;
- m_max_hbp_supported = hwdebug_info.num_instruction_bps;
- m_refresh_hwdebug_info = false;
-
- return error;
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteHardwareDebugRegs() {
- struct ppc_hw_breakpoint reg_state;
- Status error;
- long ret;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- reg_state.addr = m_hwp_regs[i].address;
- reg_state.trigger_type = m_hwp_regs[i].mode;
- reg_state.version = 1;
- reg_state.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- reg_state.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- reg_state.addr2 = 0;
- reg_state.condition_value = 0;
-
- error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_SETHWDEBUG,
- m_thread.GetID(), 0, &reg_state,
- sizeof(reg_state), &ret);
-
- if (error.Fail())
- return error;
-
- m_hwp_regs[i].slot = ret;
- }
-
- return error;
-}
-
-#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
deleted file mode 100644
index 2c4471962ad0d..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- NativeRegisterContextLinux_ppc64le.h --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This implementation is related to the OpenPOWER ABI for Power Architecture
-// 64-bit ELF V2 ABI
-
-#if defined(__powerpc64__)
-
-#ifndef lldb_NativeRegisterContextLinux_ppc64le_h
-#define lldb_NativeRegisterContextLinux_ppc64le_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
-
-#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
-#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_ppc64le : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_ppc64le(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- //------------------------------------------------------------------
- // Hardware watchpoint management functions
- //------------------------------------------------------------------
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t GetWatchpointSize(uint32_t wp_index);
-
- bool WatchpointIsEnabled(uint32_t wp_index);
-
-protected:
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status DoWriteFPR(void *buf, size_t buf_size) override;
-
- bool IsVMX(unsigned reg);
-
- bool IsVSX(unsigned reg);
-
- Status ReadVMX();
-
- Status WriteVMX();
-
- Status ReadVSX();
-
- Status WriteVSX();
-
- void *GetGPRBuffer() override { return &m_gpr_ppc64le; }
-
- void *GetFPRBuffer() override { return &m_fpr_ppc64le; }
-
- size_t GetFPRSize() override { return sizeof(m_fpr_ppc64le); }
-
-private:
- GPR m_gpr_ppc64le; // 64-bit general purpose registers.
- FPR m_fpr_ppc64le; // floating-point registers including extended register.
- VMX m_vmx_ppc64le; // VMX registers.
- VSX m_vsx_ppc64le; // Last lower bytes from first VSX registers.
-
- bool IsGPR(unsigned reg) const;
-
- bool IsFPR(unsigned reg) const;
-
- bool IsVMX(unsigned reg) const;
-
- bool IsVSX(unsigned reg) const;
-
- uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
-
- uint32_t CalculateVmxOffset(const RegisterInfo *reg_info) const;
-
- uint32_t CalculateVsxOffset(const RegisterInfo *reg_info) const;
-
- Status ReadHardwareDebugInfo();
-
- Status WriteHardwareDebugRegs();
-
- // Debug register info for hardware 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 reference counter.
- long slot; // Saves the value returned from PTRACE_SETHWDEBUG.
- int mode; // Defines if watchpoint is read/write/access.
- };
-
- std::array<DREG, 4> m_hwp_regs;
-
- // 16 is just a maximum value, query hardware for actual watchpoint count
- uint32_t m_max_hwp_supported = 16;
- uint32_t m_max_hbp_supported = 16;
- bool m_refresh_hwdebug_info = true;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_ppc64le_h
-
-#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
deleted file mode 100644
index 1bc916b69bcd1..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ /dev/null
@@ -1,638 +0,0 @@
-//===-- NativeRegisterContextLinux_s390x.cpp --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__s390x__) && defined(__linux__)
-
-#include "NativeRegisterContextLinux_s390x.h"
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
-
-#include <asm/ptrace.h>
-#include <linux/uio.h>
-#include <sys/ptrace.h>
-
-using namespace lldb_private;
-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},
-};
-}
-
-#define REG_CONTEXT_SIZE (sizeof(s390_regs) + sizeof(s390_fp_regs) + 4)
-
-// ----------------------------------------------------------------------------
-// Required ptrace defines.
-// ----------------------------------------------------------------------------
-
-#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
-#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return llvm::make_unique<NativeRegisterContextLinux_s390x>(target_arch,
- native_thread);
-}
-
-// ----------------------------------------------------------------------------
-// NativeRegisterContextLinux_s390x members.
-// ----------------------------------------------------------------------------
-
-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)
- : NativeRegisterContextLinux(native_thread,
- 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;
-}
-
-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;
- }
-
- return nullptr;
-}
-
-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);
-}
-
-Status
-NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Status("register \"%s\" is an internal-only lldb register, cannot "
- "read directly",
- reg_info->name);
-
- if (IsGPR(reg)) {
- s390_regs regs;
- Status 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 Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Status();
- }
-
- if (IsFPR(reg)) {
- s390_fp_regs fp_regs;
- Status 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 Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Status();
- }
-
- if (reg == lldb_last_break_s390x) {
- uint64_t last_break;
- Status error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
- if (error.Fail())
- return error;
-
- reg_value.SetUInt64(last_break);
- return Status();
- }
-
- if (reg == lldb_system_call_s390x) {
- uint32_t system_call;
- Status error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- if (error.Fail())
- return error;
-
- reg_value.SetUInt32(system_call);
- return Status();
- }
-
- return Status("failed - register wasn't recognized");
-}
-
-Status NativeRegisterContextLinux_s390x::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Status("register \"%s\" is an internal-only lldb register, cannot "
- "write directly",
- reg_info->name);
-
- if (IsGPR(reg)) {
- s390_regs regs;
- Status 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 Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteGPR(&regs, sizeof(regs));
- }
-
- if (IsFPR(reg)) {
- s390_fp_regs fp_regs;
- Status 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 Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteFPR(&fp_regs, sizeof(fp_regs));
- }
-
- if (reg == lldb_last_break_s390x) {
- return Status("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);
- }
-
- return Status("failed - register wasn't recognized");
-}
-
-Status NativeRegisterContextLinux_s390x::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status 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;
- }
-
- 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;
- }
-
- error = DoReadGPR(dst, sizeof(s390_regs));
- dst += sizeof(s390_regs);
- if (error.Fail())
- return error;
-
- error = DoReadFPR(dst, sizeof(s390_fp_regs));
- dst += sizeof(s390_fp_regs);
- if (error.Fail())
- return error;
-
- // Ignore errors if the regset is unsupported (happens on older kernels).
- DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
- dst += 4;
-
- // 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);
-
- return error;
-}
-
-Status NativeRegisterContextLinux_s390x::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status 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;
-}
-
-Status NativeRegisterContextLinux_s390x::DoReadRegisterValue(
- uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value) {
- return Status("DoReadRegisterValue unsupported");
-}
-
-Status NativeRegisterContextLinux_s390x::DoWriteRegisterValue(
- uint32_t offset, const char *reg_name, const RegisterValue &value) {
- return Status("DoWriteRegisterValue unsupported");
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status 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);
-}
-
-Status NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- per_lowcore_bits per_lowcore;
-
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- if (m_watchpoint_addr == LLDB_INVALID_ADDRESS) {
- is_hit = false;
- return Status();
- }
-
- Status 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 Status();
-}
-
-Status 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;
- Status 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 Status();
-}
-
-Status NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;
-
- return Status();
-}
-
-bool NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- per_struct per_info;
-
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- Status 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;
-
- 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;
-}
-
-Status NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints() {
- if (ClearHardwareWatchpoint(0))
- return Status();
- return Status("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;
-
- if (watch_flags != 0x1)
- return LLDB_INVALID_INDEX32;
-
- if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_INDEX32;
-
- Status 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;
-
- 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;
-}
-
-lldb::addr_t
-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;
-}
-
-#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
deleted file mode 100644
index 57b1a0481512f..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- NativeRegisterContextLinux_s390x.h ----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__s390x__) && defined(__linux__)
-
-#ifndef lldb_NativeRegisterContextLinux_s390x_h
-#define lldb_NativeRegisterContextLinux_s390x_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/RegisterContext_s390x.h"
-#include "Plugins/Process/Utility/lldb-s390x-register-enums.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() 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;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
-protected:
- Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value) override;
-
- Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value) override;
-
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status 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;
-
- 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 methods.
- bool IsRegisterSetAvailable(uint32_t set_index) const;
-
- bool IsGPR(uint32_t reg_index) const;
-
- bool IsFPR(uint32_t reg_index) const;
-
- Status PeekUserArea(uint32_t offset, void *buf, size_t buf_size);
-
- Status PokeUserArea(uint32_t offset, const void *buf, size_t buf_size);
-
- Status DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size);
-
- Status DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size);
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_s390x_h
-
-#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
deleted file mode 100755
index 50bf29b094df0..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ /dev/null
@@ -1,1213 +0,0 @@
-//===-- NativeRegisterContextLinux_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.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#include "NativeRegisterContextLinux_x86_64.h"
-
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.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;
-
-// ----------------------------------------------------------------------------
-// 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");
-
-// 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))
-
-// ----------------------------------------------------------------------------
-// Required ptrace defines.
-// ----------------------------------------------------------------------------
-
-// Support ptrace extensions even when compiled without required kernel support
-#ifndef NT_X86_XSTATE
-#define NT_X86_XSTATE 0x202
-#endif
-#ifndef NT_PRXFPREG
-#define NT_PRXFPREG 0x46e62b7f
-#endif
-
-// 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;
-}
-
-// ----------------------------------------------------------------------------
-// Required MPX define.
-// ----------------------------------------------------------------------------
-
-// Support MPX extensions also if compiled with compiler without MPX support.
-#ifndef bit_MPX
-#define bit_MPX 0x4000
-#endif
-
-// ----------------------------------------------------------------------------
-// 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)
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return std::unique_ptr<NativeRegisterContextLinux>(
- new NativeRegisterContextLinux_x86_64(target_arch, native_thread));
-}
-
-// ----------------------------------------------------------------------------
-// NativeRegisterContextLinux_x86_64 members.
-// ----------------------------------------------------------------------------
-
-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);
- }
-}
-
-NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- 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;
- m_iovec.iov_len = sizeof(m_fpr);
-
- // Clear out the FPR state.
- ::memset(&m_fpr, 0, sizeof(m_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::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;
- }
-
- return nullptr;
-}
-
-Status
-NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status 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) || 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];
- }
-
- 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 (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.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.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.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;
- }
- }
-
- if (reg_value.GetType() != RegisterValue::eTypeBytes)
- error.SetErrorString(
- "write failed - type was expected to be RegisterValue::eTypeBytes");
-
- return error;
- }
-
- error.SetErrorString("byte order is invalid");
- return error;
- }
-
- // Get pointer to m_fpr.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;
-}
-
-void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
- uint32_t reg_index) {
- XSAVE_HDR::XFeature &xstate_bv = m_fpr.xsave.header.xstate_bv;
- if (IsFPR(reg_index)) {
- // IsFPR considers both %st and %xmm registers as floating point, but these
- // map to two features. Set both flags, just in case.
- xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
- } else if (IsAVX(reg_index)) {
- // Lower bytes of some %ymm registers are shared with %xmm registers.
- xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
- } else if (IsMPX(reg_index)) {
- // MPX registers map to two XSAVE features.
- xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
- }
-}
-
-Status 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 Status("no lldb regnum for %s", reg_info && reg_info->name
- ? reg_info->name
- : "<unknown register>");
-
- UpdateXSTATEforWrite(reg_index);
-
- 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.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.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.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 Status("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 Status("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 Status("CopyMPXtoXSTATE() failed");
- }
- } else {
- // Get pointer to m_fpr.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 Status("unhandled register data size %" PRIu32,
- reg_info->byte_size);
- }
- }
-
- Status error = WriteFPR();
- if (error.Fail())
- return error;
-
- if (IsAVX(reg_index)) {
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Status("CopyYMMtoXSTATE() failed");
- }
-
- if (IsMPX(reg_index)) {
- if (!CopyMPXtoXSTATE(reg_index))
- return Status("CopyMPXtoXSTATE() failed");
- }
- return Status();
- }
- return Status("failed - register wasn't recognized to be a GPR or an FPR, "
- "write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
- dst += GetRegisterInfoInterface().GetGPRSize();
- if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.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;
- }
- }
- }
-
- 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");
-
- if (reg_info != nullptr)
- return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
-
- return error;
-}
-
-Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormatv(
- "data_sp contained mismatched data size, expected {0}, actual {1}",
- 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());
-
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- src += GetRegisterInfoInterface().GetGPRSize();
- if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
- else if (m_xstate_type == XStateType::XSAVE)
- ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
-
- error = WriteFPR();
- if (error.Fail())
- 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;
- }
- }
- }
-
- 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;
-}
-
-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.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.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
- return true;
- break;
- }
- return false;
-}
-
-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::IsFPR(uint32_t reg_index) const {
- return (m_reg_info.first_fpr <= reg_index &&
- reg_index <= m_reg_info.last_fpr);
-}
-
-Status NativeRegisterContextLinux_x86_64::WriteFPR() {
- switch (m_xstate_type) {
- case XStateType::FXSAVE:
- return WriteRegisterSet(
- &m_iovec, sizeof(m_fpr.fxsave),
- fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
- case XStateType::XSAVE:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
- default:
- return Status("Unrecognized FPR type.");
- }
-}
-
-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);
-}
-
-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.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.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.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.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::CopyYMMtoXSTATE(
- uint32_t reg, lldb::ByteOrder byte_order) {
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == lldb::eByteOrderLittle) {
- ::memcpy(m_fpr.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.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.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.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
-}
-
-void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
- switch (m_xstate_type) {
- case XStateType::FXSAVE:
- return &m_fpr.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.fxsave);
- case XStateType::XSAVE:
- return sizeof(m_iovec);
- default:
- return 0;
- }
-}
-
-Status NativeRegisterContextLinux_x86_64::ReadFPR() {
- Status error;
-
- // 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.xsave), NT_X86_XSTATE);
- if (!error.Fail()) {
- m_xstate_type = XStateType::XSAVE;
- return error;
- }
- }
- error = ReadRegisterSet(
- &m_iovec, sizeof(m_fpr.xsave),
- fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
- if (!error.Fail()) {
- m_xstate_type = XStateType::FXSAVE;
- return error;
- }
- return Status("Unrecognized FPR type.");
-}
-
-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);
-}
-
-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.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.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
- sizeof(MPXCsr));
- }
- return true;
-}
-
-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.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.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
- m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
- }
- return true;
-}
-
-Status NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- RegisterValue reg_value;
- Status 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();
-
- is_hit = status_bits & (1 << wp_index);
-
- return error;
-}
-
-Status 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;
- Status 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 Status();
-}
-
-Status NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- RegisterValue reg_value;
- Status 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();
-
- is_vacant = !(control_bits & (1 << (2 * wp_index)));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
-
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("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;
-
- if (watch_flags != 0x1 && watch_flags != 0x3)
- return Status("Invalid read/write bits for watchpoint");
-
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return Status("Invalid size for watchpoint");
-
- bool is_vacant;
- Status error = IsWatchpointVacant(wp_index, is_vacant);
- if (error.Fail())
- return error;
- if (!is_vacant)
- return Status("Watchpoint index not vacant");
-
- RegisterValue reg_value;
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail())
- return error;
-
- // 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 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);
-
- // 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 bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
-
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-
- control_bits |= enable_bit | rw_bits | size_bits;
-
- error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
- if (error.Fail())
- return error;
-
- 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)
- Status 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();
-}
-
-Status NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() {
- RegisterValue reg_value;
-
- // clear bits {0-4} of the debug status register (DR6)
- Status 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;
- Status 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;
-}
-
-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();
-}
-
-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
deleted file mode 100644
index 9dcf82f50a458..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- NativeRegisterContextLinux_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.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#ifndef lldb_NativeRegisterContextLinux_x86_64_h
-#define lldb_NativeRegisterContextLinux_x86_64_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
-#include <sys/uio.h>
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status 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;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
-protected:
- void *GetGPRBuffer() override { return &m_gpr_x86_64; }
-
- void *GetFPRBuffer() override;
-
- size_t GetFPRSize() override;
-
- Status ReadFPR() override;
-
- Status WriteFPR() override;
-
-private:
- // Private member types.
- enum class XStateType { Invalid, FXSAVE, XSAVE };
- enum class RegSet { gpr, fpu, avx, mpx };
-
- // 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;
- };
-
- // Private member variables.
- mutable XStateType m_xstate_type;
- FPR m_fpr; // Extended States Area, named FPR for historical reasons.
- struct 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;
-
- // Private member methods.
- bool IsCPUFeatureAvailable(RegSet feature_code) const;
-
- bool IsRegisterSetAvailable(uint32_t set_index) const;
-
- bool IsGPR(uint32_t reg_index) const;
-
- bool IsFPR(uint32_t reg_index) const;
-
- 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 CopyXSTATEtoMPX(uint32_t reg);
-
- bool CopyMPXtoXSTATE(uint32_t reg);
-
- bool IsMPX(uint32_t reg_index) const;
-
- void UpdateXSTATEforWrite(uint32_t reg_index);
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_x86_64_h
-
-#endif // defined(__i386__) || defined(__x86_64__)
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
deleted file mode 100644
index b64689c9d17b0..0000000000000
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ /dev/null
@@ -1,451 +0,0 @@
-//===-- NativeThreadLinux.cpp --------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeThreadLinux.h"
-
-#include <signal.h>
-#include <sstream>
-
-#include "NativeProcessLinux.h"
-#include "NativeRegisterContextLinux.h"
-#include "SingleStepCheck.h"
-
-#include "lldb/Host/HostNativeThread.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Host/linux/Support.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-#include "lldb/lldb-enumerations.h"
-
-#include "llvm/ADT/SmallString.h"
-
-#include "Plugins/Process/POSIX/CrashReason.h"
-
-#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)
-
-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));
- }
-}
-}
-
-NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
- lldb::tid_t tid)
- : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
- m_stop_info(),
- m_reg_context_up(
- NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- process.GetArchitecture(), *this)),
- m_stop_description() {}
-
-std::string NativeThreadLinux::GetName() {
- NativeProcessLinux &process = GetProcess();
-
- auto BufferOrError = getProcFile(process.GetID(), GetID(), "comm");
- if (!BufferOrError)
- return "";
- return BufferOrError.get()->getBuffer().rtrim('\n');
-}
-
-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;
-
- 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;
- }
- llvm_unreachable("unhandled StateType!");
-}
-
-Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags, bool hardware) {
- if (!hardware)
- return Status("not implemented");
- if (m_state == eStateLaunching)
- return Status();
- Status error = RemoveWatchpoint(addr);
- if (error.Fail())
- return error;
- uint32_t wp_index =
- m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
- if (wp_index == LLDB_INVALID_INDEX32)
- return Status("Setting hardware watchpoint failed.");
- m_watchpoint_index_map.insert({addr, wp_index});
- return Status();
-}
-
-Status NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
- auto wp = m_watchpoint_index_map.find(addr);
- if (wp == m_watchpoint_index_map.end())
- return Status();
- uint32_t wp_index = wp->second;
- m_watchpoint_index_map.erase(wp);
- if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
- return Status();
- return Status("Clearing hardware watchpoint failed.");
-}
-
-Status NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- if (m_state == eStateLaunching)
- return Status();
-
- Status error = RemoveHardwareBreakpoint(addr);
- if (error.Fail())
- return error;
-
- uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
-
- if (bp_index == LLDB_INVALID_INDEX32)
- return Status("Setting hardware breakpoint failed.");
-
- m_hw_break_index_map.insert({addr, bp_index});
- return Status();
-}
-
-Status NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
- auto bp = m_hw_break_index_map.find(addr);
- if (bp == m_hw_break_index_map.end())
- return Status();
-
- uint32_t bp_index = bp->second;
- if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
- m_hw_break_index_map.erase(bp);
- return Status();
- }
-
- return Status("Clearing hardware breakpoint failed.");
-}
-
-Status 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();
- m_reg_context_up->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);
- }
- }
-
- // Set all active hardware breakpoint on all threads.
- if (m_hw_break_index_map.empty()) {
- NativeProcessLinux &process = GetProcess();
-
- const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
- m_reg_context_up->ClearAllHardwareBreakpoints();
- for (const auto &pair : hw_breakpoint_map) {
- const auto &bp = pair.second;
- SetHardwareBreakpoint(bp.m_addr, bp.m_size);
- }
- }
-
- intptr_t data = 0;
-
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
-
- return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr,
- reinterpret_cast<void *>(data));
-}
-
-Status NativeThreadLinux::SingleStep(uint32_t signo) {
- const StateType new_state = StateType::eStateStepping;
- MaybeLogStateChange(new_state);
- m_state = new_state;
- m_stop_info.reason = StopReason::eStopReasonNone;
-
- if(!m_step_workaround) {
- // If we already hava a workaround inplace, don't reset it. Otherwise, the
- // destructor of the existing instance will run after the new instance has
- // fetched the cpu mask, and the thread will end up with the wrong mask.
- m_step_workaround = SingleStepWorkaround::Get(m_tid);
- }
-
- 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, *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;
- }
-
- // Regardless, we are stopped.
- return true;
-}
-
-void NativeThreadLinux::SetStopped() {
- if (m_state == StateType::eStateStepping)
- m_step_workaround.reset();
-
- 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__);
-
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonExec;
- m_stop_info.details.signal.signo = SIGSTOP;
-}
-
-void NativeThreadLinux::SetStoppedByBreakpoint() {
- SetStopped();
-
- 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();
-
- lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
-
- std::ostringstream ostr;
- ostr << m_reg_context_up->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 << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
-
- m_stop_description = ostr.str();
-
- 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::IsStoppedAtWatchpoint() {
- return GetState() == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonWatchpoint;
-}
-
-void NativeThreadLinux::SetStoppedByTrace() {
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonTrace;
- m_stop_info.details.signal.signo = SIGTRAP;
-}
-
-void NativeThreadLinux::SetStoppedWithNoReason() {
- SetStopped();
-
- 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;
-
- m_stop_info.reason = StopReason::eStopReasonThreadExiting;
-}
-
-Status NativeThreadLinux::RequestStop() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
-
- NativeProcessLinux &process = GetProcess();
-
- 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);
-
- Status 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());
- }
-
- 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;
-
- LLDB_LOG(log, "pid={0}, tid={1}: changing from state {2} to {3}",
- m_process.GetID(), GetID(), old_state, new_state);
-}
-
-NativeProcessLinux &NativeThreadLinux::GetProcess() {
- return static_cast<NativeProcessLinux &>(m_process);
-}
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.h b/source/Plugins/Process/Linux/NativeThreadLinux.h
deleted file mode 100644
index a7c4e982012d2..0000000000000
--- a/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ /dev/null
@@ -1,119 +0,0 @@
-//===-- NativeThreadLinux.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_NativeThreadLinux_H_
-#define liblldb_NativeThreadLinux_H_
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Linux/SingleStepCheck.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/lldb-private-forward.h"
-
-#include <csignal>
-#include <map>
-#include <memory>
-#include <string>
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeThreadLinux : public NativeThreadProtocol {
- friend class NativeProcessLinux;
-
-public:
- NativeThreadLinux(NativeProcessLinux &process, lldb::tid_t tid);
-
- // ---------------------------------------------------------------------
- // NativeThreadProtocol Interface
- // ---------------------------------------------------------------------
- std::string GetName() override;
-
- lldb::StateType GetState() override;
-
- bool GetStopReason(ThreadStopInfo &stop_info,
- std::string &description) override;
-
- NativeRegisterContextLinux &GetRegisterContext() override {
- return *m_reg_context_up;
- }
-
- Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
- bool hardware) override;
-
- Status RemoveWatchpoint(lldb::addr_t addr) override;
-
- Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
-
-private:
- // ---------------------------------------------------------------------
- // Interface for friend classes
- // ---------------------------------------------------------------------
-
- /// Resumes the thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Status Resume(uint32_t signo);
-
- /// Single steps the thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Status SingleStep(uint32_t signo);
-
- 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);
-
- void SetStoppedByExec();
-
- void SetStoppedByBreakpoint();
-
- void SetStoppedByWatchpoint(uint32_t wp_index);
-
- bool IsStoppedAtBreakpoint();
-
- bool IsStoppedAtWatchpoint();
-
- void SetStoppedByTrace();
-
- void SetStoppedWithNoReason();
-
- void SetExited();
-
- Status RequestStop();
-
- // ---------------------------------------------------------------------
- // Private interface
- // ---------------------------------------------------------------------
- void MaybeLogStateChange(lldb::StateType new_state);
-
- NativeProcessLinux &GetProcess();
-
- void SetStopped();
-
- // ---------------------------------------------------------------------
- // Member Variables
- // ---------------------------------------------------------------------
- lldb::StateType m_state;
- ThreadStopInfo m_stop_info;
- std::unique_ptr<NativeRegisterContextLinux> m_reg_context_up;
- std::string m_stop_description;
- using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
- WatchpointIndexMap m_watchpoint_index_map;
- WatchpointIndexMap m_hw_break_index_map;
- std::unique_ptr<SingleStepWorkaround> m_step_workaround;
-};
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef liblldb_NativeThreadLinux_H_
diff --git a/source/Plugins/Process/Linux/ProcessorTrace.cpp b/source/Plugins/Process/Linux/ProcessorTrace.cpp
deleted file mode 100644
index 505c526ab70d7..0000000000000
--- a/source/Plugins/Process/Linux/ProcessorTrace.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-//===-- ProcessorTrace.cpp ------------------------------------ -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <algorithm>
-#include <fstream>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "ProcessorTrace.h"
-#include "lldb/Host/linux/Support.h"
-
-#include <sys/syscall.h>
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace process_linux;
-using namespace llvm;
-
-lldb::user_id_t ProcessorTraceMonitor::m_trace_num = 1;
-
-Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Status error;
-
- config.setType(lldb::TraceType::eTraceTypeProcessorTrace);
- config.setMetaDataBufferSize(m_mmap_meta->data_size);
-
- config.setTraceBufferSize(m_mmap_meta->aux_size);
-
- error = GetCPUType(config);
-
- return error;
-#endif
-}
-
-Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
- const TraceOptions &config) {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Status error;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- LLDB_LOG(log, "called thread id {0}", tid);
- uint64_t page_size = getpagesize();
- uint64_t bufsize = config.getTraceBufferSize();
- uint64_t metabufsize = config.getMetaDataBufferSize();
-
- uint64_t numpages = static_cast<uint64_t>(
- llvm::PowerOf2Floor((bufsize + page_size - 1) / page_size));
- numpages = std::max<uint64_t>(1, numpages);
- bufsize = page_size * numpages;
-
- numpages = static_cast<uint64_t>(
- llvm::PowerOf2Floor((metabufsize + page_size - 1) / page_size));
- metabufsize = page_size * numpages;
-
- perf_event_attr attr;
- memset(&attr, 0, sizeof(attr));
- attr.size = sizeof(attr);
- attr.exclude_kernel = 1;
- attr.sample_type = PERF_SAMPLE_TIME;
- attr.sample_id_all = 1;
- attr.exclude_hv = 1;
- attr.exclude_idle = 1;
- attr.mmap = 1;
-
- int intel_pt_type = 0;
-
- auto ret = llvm::MemoryBuffer::getFileAsStream(
- "/sys/bus/event_source/devices/intel_pt/type");
- if (!ret) {
- LLDB_LOG(log, "failed to open Config file");
- return ret.getError();
- }
-
- StringRef rest = ret.get()->getBuffer();
- if (rest.empty() || rest.trim().getAsInteger(10, intel_pt_type)) {
- LLDB_LOG(log, "failed to read Config file");
- error.SetErrorString("invalid file");
- return error;
- }
-
- rest.trim().getAsInteger(10, intel_pt_type);
- LLDB_LOG(log, "intel pt type {0}", intel_pt_type);
- attr.type = intel_pt_type;
-
- LLDB_LOG(log, "meta buffer size {0}", metabufsize);
- LLDB_LOG(log, "buffer size {0} ", bufsize);
-
- if (error.Fail()) {
- LLDB_LOG(log, "Status in custom config");
-
- return error;
- }
-
- errno = 0;
- auto fd =
- syscall(SYS_perf_event_open, &attr, static_cast<::tid_t>(tid), -1, -1, 0);
- if (fd == -1) {
- LLDB_LOG(log, "syscall error {0}", errno);
- error.SetErrorString("perf event syscall Failed");
- return error;
- }
-
- m_fd = std::unique_ptr<int, file_close>(new int(fd), file_close());
-
- errno = 0;
- auto base =
- mmap(NULL, (metabufsize + page_size), PROT_WRITE, MAP_SHARED, fd, 0);
-
- if (base == MAP_FAILED) {
- LLDB_LOG(log, "mmap base error {0}", errno);
- error.SetErrorString("Meta buffer allocation failed");
- return error;
- }
-
- m_mmap_meta = std::unique_ptr<perf_event_mmap_page, munmap_delete>(
- reinterpret_cast<perf_event_mmap_page *>(base),
- munmap_delete(metabufsize + page_size));
-
- m_mmap_meta->aux_offset = m_mmap_meta->data_offset + m_mmap_meta->data_size;
- m_mmap_meta->aux_size = bufsize;
-
- errno = 0;
- auto mmap_aux = mmap(NULL, bufsize, PROT_READ, MAP_SHARED, fd,
- static_cast<long int>(m_mmap_meta->aux_offset));
-
- if (mmap_aux == MAP_FAILED) {
- LLDB_LOG(log, "second mmap done {0}", errno);
- error.SetErrorString("Trace buffer allocation failed");
- return error;
- }
- m_mmap_aux = std::unique_ptr<uint8_t, munmap_delete>(
- reinterpret_cast<uint8_t *>(mmap_aux), munmap_delete(bufsize));
- return error;
-#endif
-}
-
-llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetDataBuffer() {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- return MutableArrayRef<uint8_t>(
- (reinterpret_cast<uint8_t *>(m_mmap_meta.get()) +
- m_mmap_meta->data_offset),
- m_mmap_meta->data_size);
-#endif
-}
-
-llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetAuxBuffer() {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- return MutableArrayRef<uint8_t>(m_mmap_aux.get(), m_mmap_meta->aux_size);
-#endif
-}
-
-Status ProcessorTraceMonitor::GetCPUType(TraceOptions &config) {
-
- Status error;
- uint64_t cpu_family = -1;
- uint64_t model = -1;
- uint64_t stepping = -1;
- std::string vendor_id;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- auto BufferOrError = getProcFile("cpuinfo");
- if (!BufferOrError)
- return BufferOrError.getError();
-
- LLDB_LOG(log, "GetCPUType Function");
-
- StringRef Rest = BufferOrError.get()->getBuffer();
- while (!Rest.empty()) {
- StringRef Line;
- std::tie(Line, Rest) = Rest.split('\n');
-
- SmallVector<StringRef, 2> columns;
- Line.split(columns, StringRef(":"), -1, false);
-
- if (columns.size() < 2)
- continue; // continue searching
-
- columns[1] = columns[1].trim(" ");
- if (columns[0].contains("cpu family") &&
- columns[1].getAsInteger(10, cpu_family))
- continue;
-
- else if (columns[0].contains("model") && columns[1].getAsInteger(10, model))
- continue;
-
- else if (columns[0].contains("stepping") &&
- columns[1].getAsInteger(10, stepping))
- continue;
-
- else if (columns[0].contains("vendor_id")) {
- vendor_id = columns[1].str();
- if (!vendor_id.empty())
- continue;
- }
- LLDB_LOG(log, "{0}:{1}:{2}:{3}", cpu_family, model, stepping, vendor_id);
-
- if ((cpu_family != static_cast<uint64_t>(-1)) &&
- (model != static_cast<uint64_t>(-1)) &&
- (stepping != static_cast<uint64_t>(-1)) && (!vendor_id.empty())) {
- auto params_dict = std::make_shared<StructuredData::Dictionary>();
- params_dict->AddIntegerItem("cpu_family", cpu_family);
- params_dict->AddIntegerItem("cpu_model", model);
- params_dict->AddIntegerItem("cpu_stepping", stepping);
- params_dict->AddStringItem("cpu_vendor", vendor_id);
-
- llvm::StringRef intel_custom_params_key("intel-pt");
-
- auto intel_custom_params = std::make_shared<StructuredData::Dictionary>();
- intel_custom_params->AddItem(
- intel_custom_params_key,
- StructuredData::ObjectSP(std::move(params_dict)));
-
- config.setTraceParams(intel_custom_params);
- return error; // we are done
- }
- }
-
- error.SetErrorString("cpu info not found");
- return error;
-}
-
-llvm::Expected<ProcessorTraceMonitorUP>
-ProcessorTraceMonitor::Create(lldb::pid_t pid, lldb::tid_t tid,
- const TraceOptions &config,
- bool useProcessSettings) {
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- Status error;
- if (tid == LLDB_INVALID_THREAD_ID) {
- error.SetErrorString("thread not specified");
- return error.ToError();
- }
-
- ProcessorTraceMonitorUP pt_monitor_up(new ProcessorTraceMonitor);
-
- error = pt_monitor_up->StartTrace(pid, tid, config);
- if (error.Fail())
- return error.ToError();
-
- pt_monitor_up->SetThreadID(tid);
-
- if (useProcessSettings) {
- pt_monitor_up->SetTraceID(0);
- } else {
- pt_monitor_up->SetTraceID(m_trace_num++);
- LLDB_LOG(log, "Trace ID {0}", m_trace_num);
- }
- return std::move(pt_monitor_up);
-}
-
-Status
-ProcessorTraceMonitor::ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- Status error;
- uint64_t head = m_mmap_meta->aux_head;
-
- LLDB_LOG(log, "Aux size -{0} , Head - {1}", m_mmap_meta->aux_size, head);
-
- /**
- * When configured as ring buffer, the aux buffer keeps wrapping around
- * the buffer and its not possible to detect how many times the buffer
- * wrapped. Initially the buffer is filled with zeros,as shown below
- * so in order to get complete buffer we first copy firstpartsize, followed
- * by any left over part from beginning to aux_head
- *
- * aux_offset [d,d,d,d,d,d,d,d,0,0,0,0,0,0,0,0,0,0,0] aux_size
- * aux_head->||<- firstpartsize ->|
- *
- * */
-
- ReadCyclicBuffer(buffer, GetAuxBuffer(), static_cast<size_t>(head), offset);
- LLDB_LOG(log, "ReadCyclic BUffer Done");
- return error;
-#endif
-}
-
-Status
-ProcessorTraceMonitor::ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- uint64_t bytes_remaining = buffer.size();
- Status error;
-
- uint64_t head = m_mmap_meta->data_head;
-
- /*
- * The data buffer and aux buffer have different implementations
- * with respect to their definition of head pointer. In the case
- * of Aux data buffer the head always wraps around the aux buffer
- * and we don't need to care about it, whereas the data_head keeps
- * increasing and needs to be wrapped by modulus operator
- */
-
- LLDB_LOG(log, "bytes_remaining - {0}", bytes_remaining);
-
- auto data_buffer = GetDataBuffer();
-
- if (head > data_buffer.size()) {
- head = head % data_buffer.size();
- LLDB_LOG(log, "Data size -{0} Head - {1}", m_mmap_meta->data_size, head);
-
- ReadCyclicBuffer(buffer, data_buffer, static_cast<size_t>(head), offset);
- bytes_remaining -= buffer.size();
- } else {
- LLDB_LOG(log, "Head - {0}", head);
- if (offset >= head) {
- LLDB_LOG(log, "Invalid Offset ");
- error.SetErrorString("invalid offset");
- buffer = buffer.slice(buffer.size());
- return error;
- }
-
- auto data = data_buffer.slice(offset, (head - offset));
- auto remaining = std::copy(data.begin(), data.end(), buffer.begin());
- bytes_remaining -= (remaining - buffer.begin());
- }
- buffer = buffer.drop_back(bytes_remaining);
- return error;
-#endif
-}
-
-void ProcessorTraceMonitor::ReadCyclicBuffer(
- llvm::MutableArrayRef<uint8_t> &dst, llvm::MutableArrayRef<uint8_t> src,
- size_t src_cyc_index, size_t offset) {
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- if (dst.empty() || src.empty()) {
- dst = dst.drop_back(dst.size());
- return;
- }
-
- if (dst.data() == nullptr || src.data() == nullptr) {
- dst = dst.drop_back(dst.size());
- return;
- }
-
- if (src_cyc_index > src.size()) {
- dst = dst.drop_back(dst.size());
- return;
- }
-
- if (offset >= src.size()) {
- LLDB_LOG(log, "Too Big offset ");
- dst = dst.drop_back(dst.size());
- return;
- }
-
- llvm::SmallVector<MutableArrayRef<uint8_t>, 2> parts = {
- src.slice(src_cyc_index), src.take_front(src_cyc_index)};
-
- if (offset > parts[0].size()) {
- parts[1] = parts[1].slice(offset - parts[0].size());
- parts[0] = parts[0].drop_back(parts[0].size());
- } else if (offset == parts[0].size()) {
- parts[0] = parts[0].drop_back(parts[0].size());
- } else {
- parts[0] = parts[0].slice(offset);
- }
- auto next = dst.begin();
- auto bytes_left = dst.size();
- for (auto part : parts) {
- size_t chunk_size = std::min(part.size(), bytes_left);
- next = std::copy_n(part.begin(), chunk_size, next);
- bytes_left -= chunk_size;
- }
- dst = dst.drop_back(bytes_left);
-}
diff --git a/source/Plugins/Process/Linux/ProcessorTrace.h b/source/Plugins/Process/Linux/ProcessorTrace.h
deleted file mode 100644
index 6fd918c2bb58a..0000000000000
--- a/source/Plugins/Process/Linux/ProcessorTrace.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//===-- ProcessorTrace.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_ProcessorTrace_H_
-#define liblldb_ProcessorTrace_H_
-
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/TraceOptions.h"
-#include "lldb/lldb-types.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-
-#include <linux/perf_event.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-namespace lldb_private {
-
-namespace process_linux {
-
-// ---------------------------------------------------------------------
-// This class keeps track of one tracing instance of
-// Intel(R) Processor Trace on Linux OS. There is a map keeping track
-// of different tracing instances on each thread, which enables trace
-// gathering on a per thread level.
-//
-// The tracing instance is linked with a trace id. The trace id acts like
-// a key to the tracing instance and trace manipulations could be
-// performed using the trace id.
-//
-// The trace id could map to trace instances for a group of threads
-// (spanning to all the threads in the process) or a single thread.
-// The kernel interface for us is the perf_event_open.
-// ---------------------------------------------------------------------
-
-class ProcessorTraceMonitor;
-typedef std::unique_ptr<ProcessorTraceMonitor> ProcessorTraceMonitorUP;
-
-class ProcessorTraceMonitor {
-
- class munmap_delete {
- size_t m_length;
-
- public:
- munmap_delete(size_t length) : m_length(length) {}
- void operator()(void *ptr) {
- if (m_length)
- munmap(ptr, m_length);
- }
- };
-
- class file_close {
-
- public:
- file_close() = default;
- void operator()(int *ptr) {
- if (ptr == nullptr)
- return;
- if (*ptr == -1)
- return;
- close(*ptr);
- std::default_delete<int>()(ptr);
- }
- };
-
- std::unique_ptr<perf_event_mmap_page, munmap_delete> m_mmap_meta;
- std::unique_ptr<uint8_t, munmap_delete> m_mmap_aux;
- std::unique_ptr<int, file_close> m_fd;
-
- // perf_event_mmap_page *m_mmap_base;
- lldb::user_id_t m_traceid;
- lldb::tid_t m_thread_id;
-
- // Counter to track trace instances.
- static lldb::user_id_t m_trace_num;
-
- void SetTraceID(lldb::user_id_t traceid) { m_traceid = traceid; }
-
- Status StartTrace(lldb::pid_t pid, lldb::tid_t tid,
- const TraceOptions &config);
-
- llvm::MutableArrayRef<uint8_t> GetAuxBuffer();
- llvm::MutableArrayRef<uint8_t> GetDataBuffer();
-
- ProcessorTraceMonitor()
- : m_mmap_meta(nullptr, munmap_delete(0)),
- m_mmap_aux(nullptr, munmap_delete(0)), m_fd(nullptr, file_close()),
- m_traceid(LLDB_INVALID_UID), m_thread_id(LLDB_INVALID_THREAD_ID){};
-
- void SetThreadID(lldb::tid_t tid) { m_thread_id = tid; }
-
-public:
- static Status GetCPUType(TraceOptions &config);
-
- static llvm::Expected<ProcessorTraceMonitorUP>
- Create(lldb::pid_t pid, lldb::tid_t tid, const TraceOptions &config,
- bool useProcessSettings);
-
- Status ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0);
-
- Status ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0);
-
- ~ProcessorTraceMonitor() = default;
-
- lldb::tid_t GetThreadID() const { return m_thread_id; }
-
- lldb::user_id_t GetTraceID() const { return m_traceid; }
-
- Status GetTraceConfig(TraceOptions &config) const;
-
- // ---------------------------------------------------------------------
- /// Read data from a cyclic buffer
- ///
- /// @param[in] [out] buf
- /// Destination buffer, the buffer will be truncated to written size.
- ///
- /// @param[in] src
- /// Source buffer which must be a cyclic buffer.
- ///
- /// @param[in] src_cyc_index
- /// The index pointer (start of the valid data in the cyclic
- /// buffer).
- ///
- /// @param[in] offset
- /// The offset to begin reading the data in the cyclic buffer.
- // ---------------------------------------------------------------------
- static void ReadCyclicBuffer(llvm::MutableArrayRef<uint8_t> &dst,
- llvm::MutableArrayRef<uint8_t> src,
- size_t src_cyc_index, size_t offset);
-};
-} // namespace process_linux
-} // namespace lldb_private
-#endif
diff --git a/source/Plugins/Process/Linux/Procfs.h b/source/Plugins/Process/Linux/Procfs.h
deleted file mode 100644
index 1d9c9dbe273fd..0000000000000
--- a/source/Plugins/Process/Linux/Procfs.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- Procfs.h ---------------------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// source/Plugins/Process/Linux/Procfs.h defines the symbols we need from
-// sys/procfs.h on Android/Linux for all supported architectures.
-
-#include <sys/ptrace.h>
-
-#ifdef __ANDROID__
-#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 struct user_fpsimd_state elf_fpregset_t;
-#ifndef NT_FPREGSET
-#define NT_FPREGSET NT_PRFPREG
-#endif // NT_FPREGSET
-#elif defined(__mips__)
-#ifndef NT_FPREGSET
-#define NT_FPREGSET NT_PRFPREG
-#endif // NT_FPREGSET
-#endif
-#else // __ANDROID__
-#include <sys/procfs.h>
-#endif // __ANDROID__
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.cpp b/source/Plugins/Process/Linux/SingleStepCheck.cpp
deleted file mode 100644
index c57a2daf22757..0000000000000
--- a/source/Plugins/Process/Linux/SingleStepCheck.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- SingleStepCheck.cpp ----------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SingleStepCheck.h"
-
-#include <sched.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "NativeProcessLinux.h"
-
-#include "llvm/Support/Compiler.h"
-
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Utility/Status.h"
-
-using namespace lldb;
-using namespace lldb_private;
-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)
- ;
- }
-}
-
-struct ChildDeleter {
- ::pid_t pid;
-
- ~ChildDeleter() {
- int status;
- kill(pid, SIGKILL); // Kill the child.
- waitpid(pid, &status, __WALL); // Pick up the remains.
- }
-};
-
-bool WorkaroundNeeded() {
- // 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 = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- ::pid_t child_pid = fork();
- if (child_pid == -1) {
- LLDB_LOG(log, "failed to fork(): {0}", Status(errno, eErrorTypePOSIX));
- 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) {
- LLDB_LOG(log, "failed to get available cpus: {0}",
- Status(errno, eErrorTypePOSIX));
- return false;
- }
-
- int status;
- ::pid_t wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status)) {
- LLDB_LOG(log, "waitpid() failed (status = {0:x}): {1}", status,
- Status(errno, eErrorTypePOSIX));
- 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) {
- LLDB_LOG(log, "failed to switch to cpu {0}: {1}", cpu,
- Status(errno, eErrorTypePOSIX));
- continue;
- }
-
- int status;
- Status error =
- NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, child_pid);
- if (error.Fail()) {
- LLDB_LOG(log, "single step failed: {0}", error);
- break;
- }
-
- wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status)) {
- LLDB_LOG(log, "waitpid() failed (status = {0:x}): {1}", status,
- Status(errno, eErrorTypePOSIX));
- break;
- }
- if (WSTOPSIG(status) != SIGTRAP) {
- LLDB_LOG(log, "single stepping on cpu {0} failed with status {1:x}", cpu,
- status);
- break;
- }
- }
-
- // cpu is either the index of the first broken cpu, or CPU_SETSIZE.
- if (cpu == 0) {
- LLDB_LOG(log,
- "SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING "
- "LIKELY TO BE UNRELIABLE.");
- // 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;
-}
-
-} // end anonymous namespace
-
-std::unique_ptr<SingleStepWorkaround> SingleStepWorkaround::Get(::pid_t tid) {
- Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
-
- static bool workaround_needed = WorkaroundNeeded();
- if (!workaround_needed) {
- LLDB_LOG(log, "workaround for thread {0} not needed", tid);
- return nullptr;
- }
-
- cpu_set_t original_set;
- if (sched_getaffinity(tid, sizeof original_set, &original_set) != 0) {
- // This should really not fail. But, just in case...
- LLDB_LOG(log, "Unable to get cpu affinity for thread {0}: {1}", tid,
- Status(errno, eErrorTypePOSIX));
- return nullptr;
- }
-
- cpu_set_t set;
- CPU_ZERO(&set);
- CPU_SET(0, &set);
- if (sched_setaffinity(tid, sizeof set, &set) != 0) {
- // 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...
- LLDB_LOG(log, "Unable to set cpu affinity for thread {0}: {1}", tid,
- Status(errno, eErrorTypePOSIX));
- }
-
- LLDB_LOG(log, "workaround for thread {0} prepared", tid);
- return llvm::make_unique<SingleStepWorkaround>(tid, original_set);
-}
-
-SingleStepWorkaround::~SingleStepWorkaround() {
- Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "Removing workaround");
- if (sched_setaffinity(m_tid, sizeof m_original_set, &m_original_set) != 0) {
- LLDB_LOG(log, "Unable to reset cpu affinity for thread {0}: {1}", m_tid,
- Status(errno, eErrorTypePOSIX));
- }
-}
-#endif
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.h b/source/Plugins/Process/Linux/SingleStepCheck.h
deleted file mode 100644
index afeda7310349a..0000000000000
--- a/source/Plugins/Process/Linux/SingleStepCheck.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//===-- SingleStepCheck.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_SingleStepCheck_H_
-#define liblldb_SingleStepCheck_H_
-
-#include <memory>
-#include <sched.h>
-#include <sys/types.h>
-
-namespace lldb_private {
-namespace process_linux {
-
-// 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 these systems become obsolete.
-
-#if defined(__arm64__) || defined(__aarch64__)
-class SingleStepWorkaround {
- ::pid_t m_tid;
- cpu_set_t m_original_set;
-
- SingleStepWorkaround(const SingleStepWorkaround &) = delete;
- void operator=(const SingleStepWorkaround &) = delete;
-
-public:
- SingleStepWorkaround(::pid_t tid, cpu_set_t original_set)
- : m_tid(tid), m_original_set(original_set) {}
- ~SingleStepWorkaround();
-
- static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid);
-};
-#else
-class SingleStepWorkaround {
-public:
- static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid) {
- return nullptr;
- }
-};
-#endif
-
-} // end namespace process_linux
-} // end namespace lldb_private
-
-#endif // #ifndef liblldb_SingleStepCheck_H_
diff --git a/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt b/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt
deleted file mode 100644
index bed0e3b7ab377..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-add_lldb_library(lldbPluginProcessMacOSXKernel PLUGIN
- CommunicationKDP.cpp
- ProcessKDP.cpp
- ProcessKDPLog.cpp
- RegisterContextKDP_arm.cpp
- RegisterContextKDP_arm64.cpp
- RegisterContextKDP_i386.cpp
- RegisterContextKDP_x86_64.cpp
- ThreadKDP.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginDynamicLoaderDarwinKernel
- lldbPluginDynamicLoaderStatic
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
deleted file mode 100644
index 8908108eff4bd..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ /dev/null
@@ -1,1289 +0,0 @@
-//===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CommunicationKDP.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <string.h>
-
-
-#include "lldb/Core/DumpDataExtractor.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/UUID.h"
-
-#include "ProcessKDPLog.h"
-
-using namespace lldb;
-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) {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-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);
-}
-
-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;
- }
-
- 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() ==
- *((const 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,
- 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;
-}
-
-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);
- }
- return false;
-}
-
-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();
-}
-
-bool CommunicationKDP::WaitForNotRunningPrivate(
- const std::chrono::microseconds &timeout) {
- return m_is_running.WaitForValueEqualTo(false, timeout);
-}
-
-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);
-}
-
-size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock(
- DataExtractor &packet, uint32_t timeout_usec) {
- uint8_t buffer[8192];
- Status error;
-
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
-
- // 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);
-
- LLDB_LOGV(log,
- "Read (buffer, sizeof(buffer), timeout_usec = 0x{0:x}, "
- "status = {1}, error = {2}) => bytes_read = {4}",
- timeout_usec,
- Communication::ConnectionStatusAsCString(status),
- error, 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;
- }
- }
- }
- 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);
-
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
-
- if (src && src_len > 0) {
- if (log && log->GetVerbose()) {
- PacketStreamType log_strm;
- 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);
- }
-
- // 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;
-}
-
-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;
-}
-
-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::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;
-}
-
-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::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;
-
- if (uuid.SetFromStringRef(uuid_str) == 0) {
- UUID invalid_uuid;
- return invalid_uuid;
- }
-
- return uuid;
-}
-
-bool CommunicationKDP::RemoteIsEFI() {
- if (GetKernelVersion() == NULL)
- return false;
- return strncmp(m_kernel_version.c_str(), "EFI", 3) == 0;
-}
-
-bool CommunicationKDP::RemoteIsDarwinKernel() {
- if (GetKernelVersion() == NULL)
- return false;
- return m_kernel_version.find("Darwin Kernel") != std::string::npos;
-}
-
-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::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;
-}
-
-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;
-}
-
-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;
-}
-
-uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst,
- uint32_t dst_len,
- Status &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;
-}
-
-uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr,
- const void *src,
- uint32_t src_len,
- Status &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 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, Status &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;
- }
- } else {
- error.SetErrorString("failed to send packet");
- }
- return false;
-}
-
-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 void *data,
- uint32_t data_len) {
- DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size);
- DumpPacket(s, extractor);
-}
-
-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)
- DumpDataExtractor(packet,
- &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)
- DumpDataExtractor(packet,
- &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)
- DumpDataExtractor(packet,
- &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)
- DumpDataExtractor(packet,
- &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)
- 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)
- 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)
- 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)
- DumpDataExtractor(packet,
- &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)
- DumpDataExtractor(packet,
- &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)
- DumpDataExtractor(packet,
- &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)
- DumpDataExtractor(packet,
- &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);
-
- DumpDataExtractor(packet,
- &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::SendRequestReadRegisters(uint32_t cpu,
- uint32_t flavor, void *dst,
- uint32_t dst_len,
- Status &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.SetErrorStringWithFormat(
- "failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
- } else {
- error.SetErrorString("failed to send packet");
- }
- return 0;
-}
-
-uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu,
- uint32_t flavor,
- const void *src,
- uint32_t src_len,
- Status &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::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;
- return SendRequestAndGetReply(command, request_packet, reply_packet);
-}
-
-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;
- return SendRequestAndGetReply(command, request_packet, reply_packet);
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
deleted file mode 100644
index 64bfe55147350..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
+++ /dev/null
@@ -1,260 +0,0 @@
-//===-- CommunicationKDP.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_CommunicationKDP_h_
-#define liblldb_CommunicationKDP_h_
-
-#include <list>
-#include <mutex>
-#include <string>
-
-#include "lldb/Core/Communication.h"
-#include "lldb/Core/StreamBuffer.h"
-#include "lldb/Utility/Listener.h"
-#include "lldb/Utility/Predicate.h"
-#include "lldb/lldb-private.h"
-
-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.
- //------------------------------------------------------------------
- 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::Status &error);
-
- uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
- uint32_t src_len,
- lldb_private::Status &error);
-
- bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
- lldb_private::DataExtractor &reply,
- lldb_private::Status &error);
-
- uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
- uint32_t dst_size,
- lldb_private::Status &error);
-
- uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
- const void *src, uint32_t src_size,
- lldb_private::Status &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);
-
-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);
-};
-
-#endif // liblldb_CommunicationKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
deleted file mode 100644
index c1c3678617c09..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ /dev/null
@@ -1,1037 +0,0 @@
-//===-- ProcessKDP.cpp ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <stdlib.h>
-
-#include <mutex>
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandObject.h"
-#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/OptionGroupString.h"
-#include "lldb/Interpreter/OptionGroupUInt64.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/StringExtractor.h"
-#include "lldb/Utility/UUID.h"
-
-#include "llvm/Support/Threading.h"
-
-#define USEC_PER_SEC 1000000
-
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
-#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
-#include "ProcessKDP.h"
-#include "ProcessKDPLog.h"
-#include "ThreadKDP.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-static constexpr PropertyDefinition g_properties[] = {
- {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, {},
- "Specify the default packet timeout in seconds."}};
-
-enum { ePropertyPacketTimeout };
-
-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;
-}
-
-} // anonymous namespace end
-
-static const lldb::tid_t g_kernel_tid = 1;
-
-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.";
-}
-
-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;
-}
-
-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;
-}
-
-//----------------------------------------------------------------------
-// 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(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();
-}
-
-//----------------------------------------------------------------------
-// PluginInterface
-//----------------------------------------------------------------------
-lldb_private::ConstString ProcessKDP::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ProcessKDP::GetPluginVersion() { return 1; }
-
-Status ProcessKDP::WillLaunch(Module *module) {
- Status error;
- error.SetErrorString("launching not supported in kdp-remote plug-in");
- return error;
-}
-
-Status ProcessKDP::WillAttachToProcessWithID(lldb::pid_t pid) {
- Status error;
- error.SetErrorString(
- "attaching to a by process ID not supported in kdp-remote plug-in");
- return error;
-}
-
-Status ProcessKDP::WillAttachToProcessWithName(const char *process_name,
- bool wait_for_launch) {
- Status 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;
-}
-
-Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
- Status 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);
-
- 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 (FileSystem::Instance().Exists(
- executable_module_spec.GetFileSpec())) {
- module_spec.GetFileSpec() =
- executable_module_spec.GetFileSpec();
- }
- }
- if (!module_spec.GetSymbolFileSpec() ||
- !module_spec.GetSymbolFileSpec())
- Symbols::DownloadObjectAndSymbolFile(module_spec, true);
-
- if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
- 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, eLoadDependentsNo);
- }
- }
- }
- } 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("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.str().c_str());
- }
- if (error.Fail())
- m_comm.Disconnect();
-
- return error;
-}
-
-//----------------------------------------------------------------------
-// Process Control
-//----------------------------------------------------------------------
-Status ProcessKDP::DoLaunch(Module *exe_module,
- ProcessLaunchInfo &launch_info) {
- Status error;
- error.SetErrorString("launching not supported in kdp-remote plug-in");
- return error;
-}
-
-Status
-ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid,
- const ProcessAttachInfo &attach_info) {
- Status error;
- error.SetErrorString(
- "attach to process by ID is not supported in kdp remote debugging");
- return error;
-}
-
-Status
-ProcessKDP::DoAttachToProcessWithName(const char *process_name,
- const ProcessAttachInfo &attach_info) {
- Status error;
- error.SetErrorString(
- "attach to process by name is not supported in kdp remote debugging");
- return error;
-}
-
-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);
- }
-}
-
-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();
-}
-
-Status ProcessKDP::WillResume() { return Status(); }
-
-Status ProcessKDP::DoResume() {
- Status 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;
-
- default:
- // The only valid thread resume states are listed above
- llvm_unreachable("invalid thread resume state");
- }
- }
-
- 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));
- LLDB_LOGV(log, "pid = {0}", 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();
-}
-
-Status ProcessKDP::DoHalt(bool &caused_stop) {
- Status error;
-
- if (m_comm.IsRunning()) {
- if (m_destroy_in_process) {
- // If we are attempting 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;
-}
-
-Status ProcessKDP::DoDetach(bool keep_stopped) {
- Status 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;
-}
-
-Status 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();
-}
-
-//------------------------------------------------------------------
-// Process Memory
-//------------------------------------------------------------------
-size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
- Status &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;
- }
- }
-
- return total_bytes_read;
- }
- error.SetErrorString("not connected");
- return 0;
-}
-
-size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
- Status &error) {
- if (m_comm.IsConnected())
- return m_comm.SendRequestWriteMemory(addr, buf, size, error);
- error.SetErrorString("not connected");
- return 0;
-}
-
-lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
- Status &error) {
- error.SetErrorString(
- "memory allocation not supported in kdp remote debugging");
- return LLDB_INVALID_ADDRESS;
-}
-
-Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
- Status error;
- error.SetErrorString(
- "memory deallocation not supported in kdp remote debugging");
- return error;
-}
-
-Status ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {
- if (m_comm.LocalBreakpointsAreSupported()) {
- Status 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);
-}
-
-Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
- if (m_comm.LocalBreakpointsAreSupported()) {
- Status 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;
- }
- return DisableSoftwareBreakpoint(bp_site);
-}
-
-Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- error.SetErrorString(
- "watchpoints are not supported in kdp remote debugging");
- return error;
-}
-
-Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- error.SetErrorString(
- "watchpoints are not supported in kdp remote debugging");
- return error;
-}
-
-void ProcessKDP::Clear() { m_thread_list.Clear(); }
-
-Status ProcessKDP::DoSignal(int signo) {
- Status error;
- error.SetErrorString(
- "sending signals is not supported in kdp remote debugging");
- return error;
-}
-
-void ProcessKDP::Initialize() {
- static llvm::once_flag g_once_flag;
-
- llvm::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance,
- DebuggerInitialize);
-
- ProcessKDPLog::Initialize();
- });
-}
-
-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 ()");
-
- if (m_async_thread.IsJoinable())
- return true;
-
- 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));
-
- 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);
-}
-
-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;
-}
-
-class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {
-private:
- 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(),
- 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, '\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;
- }
- }
- Status 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;
- }
-};
-
-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() {}
-};
-
-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() {}
-};
-
-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
deleted file mode 100644
index f9102442de935..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ /dev/null
@@ -1,220 +0,0 @@
-//===-- ProcessKDP.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_ProcessKDP_h_
-#define liblldb_ProcessKDP_h_
-
-
-#include <list>
-#include <vector>
-
-#include "lldb/Core/ThreadSafeValue.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/Broadcaster.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/StringList.h"
-
-#include "CommunicationKDP.h"
-
-class ThreadKDP;
-
-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);
-
- ~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::Status WillLaunch(lldb_private::Module *module) override;
-
- lldb_private::Status
- DoLaunch(lldb_private::Module *exe_module,
- lldb_private::ProcessLaunchInfo &launch_info) override;
-
- lldb_private::Status WillAttachToProcessWithID(lldb::pid_t pid) override;
-
- lldb_private::Status
- WillAttachToProcessWithName(const char *process_name,
- bool wait_for_launch) override;
-
- lldb_private::Status DoConnectRemote(lldb_private::Stream *strm,
- llvm::StringRef remote_url) override;
-
- lldb_private::Status DoAttachToProcessWithID(
- lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
-
- lldb_private::Status 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::Status WillResume() override;
-
- lldb_private::Status DoResume() override;
-
- lldb_private::Status DoHalt(bool &caused_stop) override;
-
- lldb_private::Status DoDetach(bool keep_stopped) override;
-
- lldb_private::Status DoSignal(int signal) override;
-
- lldb_private::Status 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::Status &error) override;
-
- size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
- lldb_private::Status &error) override;
-
- lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
- lldb_private::Status &error) override;
-
- lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override;
-
- //----------------------------------------------------------------------
- // Process Breakpoints
- //----------------------------------------------------------------------
- lldb_private::Status
- EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- lldb_private::Status
- DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- //----------------------------------------------------------------------
- // Process Watchpoints
- //----------------------------------------------------------------------
- lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp,
- bool notify = true) override;
-
- lldb_private::Status 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();
-
- 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);
-};
-
-#endif // liblldb_ProcessKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
deleted file mode 100644
index ffab3e5e23c77..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- ProcessKDPLog.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessKDPLog.h"
-
-using namespace lldb_private;
-
-static constexpr Log::Category g_categories[] = {
- {{"async"}, {"log asynchronous activity"}, KDP_LOG_ASYNC},
- {{"break"}, {"log breakpoints"}, KDP_LOG_BREAKPOINTS},
- {{"comm"}, {"log communication activity"}, KDP_LOG_COMM},
- {{"data-long"},
- {"log memory bytes for memory reads and writes for all transactions"},
- KDP_LOG_MEMORY_DATA_LONG},
- {{"data-short"},
- {"log memory bytes for memory reads and writes for short transactions "
- "only"},
- KDP_LOG_MEMORY_DATA_SHORT},
- {{"memory"}, {"log memory reads and writes"}, KDP_LOG_MEMORY},
- {{"packets"}, {"log gdb remote packets"}, KDP_LOG_PACKETS},
- {{"process"}, {"log process events and activities"}, KDP_LOG_PROCESS},
- {{"step"}, {"log step related activities"}, KDP_LOG_STEP},
- {{"thread"}, {"log thread events and activities"}, KDP_LOG_THREAD},
- {{"watch"}, {"log watchpoint related activities"}, KDP_LOG_WATCHPOINTS},
-};
-
-Log::Channel ProcessKDPLog::g_channel(g_categories, KDP_LOG_DEFAULT);
-
-void ProcessKDPLog::Initialize() { Log::Register("kdp-remote", g_channel); }
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
deleted file mode 100644
index 908754ec992b1..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- ProcessKDPLog.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_ProcessKDPLog_h_
-#define liblldb_ProcessKDPLog_h_
-
-#include "lldb/Utility/Log.h"
-
-#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
-
-namespace lldb_private {
-class ProcessKDPLog {
- static Log::Channel g_channel;
-
-public:
- static void Initialize();
-
- static Log *GetLogIfAllCategoriesSet(uint32_t mask) {
- return g_channel.GetLogIfAll(mask);
- }
-};
-}
-
-#endif // liblldb_ProcessKDPLog_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
deleted file mode 100644
index 0f9e62ce355a0..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- RegisterContextKDP_arm.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextKDP_arm.h"
-
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-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) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
- const DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
deleted file mode 100644
index 1532f23207f42..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- RegisterContextKDP_arm.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextKDP_arm_h_
-#define liblldb_RegisterContextKDP_arm_h_
-
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_arm : public RegisterContextDarwin_arm {
-public:
- RegisterContextKDP_arm(ThreadKDP &thread, uint32_t concrete_frame_idx);
-
- 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);
-
- ThreadKDP &m_kdp_thread;
-};
-
-#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
deleted file mode 100644
index e13a7f3ad9079..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextKDP_arm64.h"
-
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextKDP_arm64::RegisterContextKDP_arm64(ThreadKDP &thread,
- uint32_t concrete_frame_idx)
- : RegisterContextDarwin_arm64(thread, concrete_frame_idx),
- m_kdp_thread(thread) {}
-
-RegisterContextKDP_arm64::~RegisterContextKDP_arm64() {}
-
-int RegisterContextKDP_arm64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteDBG(lldb::tid_t tid, int flavor,
- const DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
deleted file mode 100644
index be4038ba96eaf..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- RegisterContextKDP_arm64.h --------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextKDP_arm64_h_
-#define liblldb_RegisterContextKDP_arm64_h_
-
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 {
-public:
- RegisterContextKDP_arm64(ThreadKDP &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextKDP_arm64();
-
-protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
-
- int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
-
- int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
-
- ThreadKDP &m_kdp_thread;
-};
-
-#endif // liblldb_RegisterContextKDP_arm64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
deleted file mode 100644
index 096aa0f95d009..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- RegisterContextKDP_i386.cpp -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextKDP_i386.h"
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-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() {}
-
-int RegisterContextKDP_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
deleted file mode 100644
index 699d5fabe1570..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- RegisterContextKDP_i386.h -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextKDP_i386_h_
-#define liblldb_RegisterContextKDP_i386_h_
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 {
-public:
- 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;
-};
-
-#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
deleted file mode 100644
index 9d85145f2eaf2..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-//===-- RegisterContextKDP_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 "RegisterContextKDP_x86_64.h"
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-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() {}
-
-int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
- GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoReadFPU(lldb::tid_t tid, int flavor,
- FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
- EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
deleted file mode 100644
index 9841ad77b0044..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- RegisterContextKDP_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_RegisterContextKDP_x86_64_h_
-#define liblldb_RegisterContextKDP_x86_64_h_
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 {
-public:
- 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;
-};
-
-#endif // liblldb_RegisterContextKDP_x86_64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
deleted file mode 100644
index 6f26acd0b8aa7..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-//===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ThreadKDP.h"
-
-#include "lldb/Host/SafeMachO.h"
-
-#include "lldb/Breakpoint/Watchpoint.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/Utility/ArchSpec.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/StreamString.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"
-
-using namespace lldb;
-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) {
- Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
- LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
-}
-
-ThreadKDP::~ThreadKDP() {
- Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
- LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
- DestroyThread();
-}
-
-const char *ThreadKDP::GetName() {
- if (m_thread_name.empty())
- return nullptr;
- return m_thread_name.c_str();
-}
-
-const char *ThreadKDP::GetQueueName() { return nullptr; }
-
-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::ShouldStop(bool &step_more) { return true; }
-lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
- 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:
- llvm_unreachable("Add CPU type support in KDP");
- }
- }
- } else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- 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;
- }
- 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);
- }
- }
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
deleted file mode 100644
index ea517b4254fc9..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- ThreadKDP.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_ThreadKDP_h_
-#define liblldb_ThreadKDP_h_
-
-#include <string>
-
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
-
-class ProcessKDP;
-
-class ThreadKDP : public lldb_private::Thread {
-public:
- ThreadKDP(lldb_private::Process &process, lldb::tid_t tid);
-
- virtual ~ThreadKDP();
-
- virtual void RefreshStateAfterStop();
-
- virtual const char *GetName();
-
- virtual const char *GetQueueName();
-
- virtual lldb::RegisterContextSP GetRegisterContext();
-
- virtual lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame);
-
- void Dump(lldb_private::Log *log, uint32_t index);
-
- static bool ThreadIDIsValid(lldb::tid_t thread);
-
- bool ShouldStop(bool &step_more);
-
- const char *GetBasicInfoAsString();
-
- 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; }
-
- 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();
-};
-
-#endif // liblldb_ThreadKDP_h_
diff --git a/source/Plugins/Process/NetBSD/CMakeLists.txt b/source/Plugins/Process/NetBSD/CMakeLists.txt
deleted file mode 100644
index e131e6d70468b..0000000000000
--- a/source/Plugins/Process/NetBSD/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-add_lldb_library(lldbPluginProcessNetBSD PLUGIN
- NativeProcessNetBSD.cpp
- NativeRegisterContextNetBSD.cpp
- NativeRegisterContextNetBSD_x86_64.cpp
- NativeThreadNetBSD.cpp
-
- LINK_LIBS
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessPOSIX
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/POSIX/CMakeLists.txt b/source/Plugins/Process/POSIX/CMakeLists.txt
deleted file mode 100644
index f058e01c74394..0000000000000
--- a/source/Plugins/Process/POSIX/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginProcessPOSIX PLUGIN
- CrashReason.cpp
- ProcessMessage.cpp
- ProcessPOSIXLog.cpp
-
- LINK_LIBS
- lldbInterpreter
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
deleted file mode 100644
index e36ce4dec98a8..0000000000000
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-add_lldb_library(lldbPluginProcessUtility PLUGIN
- DynamicRegisterInfo.cpp
- FreeBSDSignals.cpp
- GDBRemoteSignals.cpp
- HistoryThread.cpp
- HistoryUnwind.cpp
- InferiorCallPOSIX.cpp
- LinuxProcMaps.cpp
- LinuxSignals.cpp
- MipsLinuxSignals.cpp
- NativeRegisterContextRegisterInfo.cpp
- NetBSDSignals.cpp
- RegisterContextDarwin_arm.cpp
- RegisterContextDarwin_arm64.cpp
- RegisterContextDarwin_i386.cpp
- RegisterContextDarwin_x86_64.cpp
- RegisterContextDummy.cpp
- RegisterContextFreeBSD_i386.cpp
- RegisterContextFreeBSD_mips64.cpp
- RegisterContextFreeBSD_powerpc.cpp
- RegisterContextFreeBSD_x86_64.cpp
- RegisterContextHistory.cpp
- RegisterContextLinux_i386.cpp
- RegisterContextLinux_x86_64.cpp
- RegisterContextLinux_mips64.cpp
- RegisterContextLinux_mips.cpp
- RegisterContextLinux_s390x.cpp
- RegisterContextLLDB.cpp
- RegisterContextMacOSXFrameBackchain.cpp
- RegisterContextMach_arm.cpp
- RegisterContextMach_i386.cpp
- RegisterContextMach_x86_64.cpp
- RegisterContextMemory.cpp
- RegisterContextNetBSD_x86_64.cpp
- RegisterContextOpenBSD_i386.cpp
- RegisterContextOpenBSD_x86_64.cpp
- RegisterContextPOSIX_arm.cpp
- RegisterContextPOSIX_arm64.cpp
- RegisterContextPOSIX_mips64.cpp
- RegisterContextPOSIX_powerpc.cpp
- RegisterContextPOSIX_ppc64le.cpp
- RegisterContextPOSIX_s390x.cpp
- RegisterContextPOSIX_x86.cpp
- RegisterContextThreadMemory.cpp
- RegisterInfoPOSIX_arm.cpp
- RegisterInfoPOSIX_arm64.cpp
- RegisterInfoPOSIX_ppc64le.cpp
- StopInfoMachException.cpp
- ThreadMemory.cpp
- UnwindLLDB.cpp
- UnwindMacOSXFrameBackchain.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbDataFormatters
- lldbExpression
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Windows/Common/CMakeLists.txt b/source/Plugins/Process/Windows/Common/CMakeLists.txt
deleted file mode 100644
index 0926290861833..0000000000000
--- a/source/Plugins/Process/Windows/Common/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-set(PROC_WINDOWS_COMMON_SOURCES
- DebuggerThread.cpp
- LocalDebugDelegate.cpp
- ProcessWindows.cpp
- ProcessWindowsLog.cpp
- RegisterContextWindows.cpp
- TargetThreadWindows.cpp
- )
-
-if (CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(PROC_WINDOWS_COMMON_SOURCES ${PROC_WINDOWS_COMMON_SOURCES}
- x86/RegisterContextWindows_x86.cpp
- )
-elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(PROC_WINDOWS_COMMON_SOURCES ${PROC_WINDOWS_COMMON_SOURCES}
- x64/RegisterContextWindows_x64.cpp
- )
-endif()
-
-add_lldb_library(lldbPluginProcessWindowsCommon PLUGIN
- ${PROC_WINDOWS_COMMON_SOURCES}
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- ws2_32
- rpcrt4
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
deleted file mode 100644
index 81ec25871c577..0000000000000
--- a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-//===-- 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/ModuleSpec.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 "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Predicate.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Threading.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;
-};
-} // namespace
-
-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); }
-
-Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "launching '{0}'", launch_info.GetExecutableFile().GetPath());
-
- Status error;
- DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread(
- "lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine,
- context, &error));
-
- if (!error.Success())
- LLDB_LOG(log, "couldn't launch debugger thread. {0}", error);
-
- return error;
-}
-
-Status DebuggerThread::DebugAttach(lldb::pid_t pid,
- const ProcessAttachInfo &attach_info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "attaching to '{0}'", pid);
-
- Status 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())
- LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, error);
-
- 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());
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "preparing to launch '{0}' on background thread.",
- launch_info.GetExecutableFile().GetPath());
-
- Status 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());
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "preparing to attach to process '{0}' on background thread.",
- pid);
-
- if (!DebugActiveProcess((DWORD)pid)) {
- Status 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;
-}
-
-Status DebuggerThread::StopDebugging(bool terminate) {
- Status error;
-
- lldb::pid_t pid = m_process.GetProcessId();
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "terminate = {0}, inferior={1}.", terminate, 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) {
- if (handle != nullptr && handle != LLDB_INVALID_PROCESS) {
- // 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);
- LLDB_LOG(log,
- "calling TerminateProcess({0}, 0) (inferior={1}), success={2}",
- handle, pid, terminate_suceeded);
- } else {
- LLDB_LOG(log,
- "NOT calling TerminateProcess because the inferior is not valid "
- "({0}, 0) (inferior={1})",
- handle, pid);
- }
- }
-
- // 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()) {
- LLDB_LOG(log, "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);
- }
- }
-
- LLDB_LOG(log, "waiting for detach from process {0} to complete.", pid);
-
- DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
- if (wait_result != WAIT_OBJECT_0) {
- error.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "error: WaitForSingleObject({0}, 5000) returned {1}",
- m_debugging_ended_event, wait_result);
- } else
- LLDB_LOG(log, "detach from process {0} completed successfully.", pid);
-
- if (!error.Success()) {
- LLDB_LOG(log, "encountered an error while trying to stop process {0}. {1}",
- pid, error);
- }
- return error;
-}
-
-void DebuggerThread::ContinueAsyncException(ExceptionResult result) {
- if (!m_active_exception.get())
- return;
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
- WINDOWS_LOG_EXCEPTION);
- LLDB_LOG(log, "broadcasting for inferior process {0}.",
- 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() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- DEBUG_EVENT dbe = {};
- bool should_debug = true;
- LLDB_LOGV(log, "Entering WaitForDebugEvent loop");
- while (should_debug) {
- LLDB_LOGV(log, "Calling WaitForDebugEvent");
- BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
- if (wait_result) {
- DWORD continue_status = DBG_CONTINUE;
- switch (dbe.dwDebugEventCode) {
- default:
- llvm_unreachable("Unhandle debug event code!");
- 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;
- }
-
- LLDB_LOGV(log, "calling ContinueDebugEvent({0}, {1}, {2}) on thread {3}.",
- dbe.dwProcessId, dbe.dwThreadId, continue_status,
- ::GetCurrentThreadId());
-
- ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
-
- if (m_detached) {
- should_debug = false;
- }
- } else {
- LLDB_LOG(log, "returned FALSE from WaitForDebugEvent. Error = {0}",
- ::GetLastError());
-
- should_debug = false;
- }
- }
- FreeProcessHandles();
-
- LLDB_LOG(log, "WaitForDebugEvent loop completed, exiting.");
- ::SetEvent(m_debugging_ended_event);
-}
-
-ExceptionResult
-DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION);
- 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) {
- LLDB_LOG(log, "Breakpoint exception is cue to detach from process {0: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));
- LLDB_LOG(log, "encountered {0} chance exception {1:x} on thread {2: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);
-
- LLDB_LOG(log, "waiting for ExceptionPred != BreakInDebugger");
- result = *m_exception_pred.WaitForValueNotEqualTo(
- ExceptionResult::BreakInDebugger);
-
- LLDB_LOG(log, "got ExceptionPred = {0}", (int)m_exception_pred.GetValue());
- return result;
-}
-
-DWORD
-DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
- LLDB_LOG(log, "Thread {0} spawned in process {1}", 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) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS);
- uint32_t process_id = ::GetProcessId(info.hProcess);
-
- LLDB_LOG(log, "process {0} 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();
- llvm::set_thread_name(thread_name);
-
- // 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) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
- LLDB_LOG(log, "Thread {0} exited with code {1} in process {2}", 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) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
- LLDB_LOG(log, "process {0} exited with code {1}", m_process.GetProcessId(),
- info.dwExitCode);
-
- m_debug_delegate->OnExitProcess(info.dwExitCode);
-
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- if (info.hFile == nullptr) {
- // Not sure what this is, so just ignore it.
- LLDB_LOG(log, "Warning: Inferior {0} 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);
- ModuleSpec module_spec(file_spec);
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
-
- LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...",
- m_process.GetProcessId(), path, info.lpBaseOfDll);
-
- m_debug_delegate->OnLoadDll(module_spec, load_addr);
- } else {
- LLDB_LOG(
- log,
- "Inferior {0} - Error {1} 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) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- LLDB_LOG(log, "process {0} unloading DLL at addr {1:x}.",
- 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) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- LLDB_LOG(log, "encountered error {0} (type={1}) in process {2} thread {3}",
- info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
-
- Status 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
deleted file mode 100644
index 047d3ccb7296b..0000000000000
--- a/source/Plugins/Process/Windows/Common/DebuggerThread.h
+++ /dev/null
@@ -1,106 +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/windows/windows.h"
-#include "lldb/Utility/Predicate.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();
-
- Status DebugLaunch(const ProcessLaunchInfo &launch_info);
- Status 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;
- }
-
- Status 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
deleted file mode 100644
index 1eec85d52c264..0000000000000
--- a/source/Plugins/Process/Windows/Common/ExceptionRecord.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- ExceptionRecord.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_ExceptionRecord_H_
-#define liblldb_Plugins_Process_Windows_ExceptionRecord_H_
-
-#include "lldb/Host/windows/windows.h"
-#include "lldb/lldb-forward.h"
-#include <dbghelp.h>
-
-#include <memory>
-#include <vector>
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-// ExceptionRecord
-//
-// 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);
- }
-
- // 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));
- }
- }
-
- 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; }
-
- 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;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/ForwardDecl.h b/source/Plugins/Process/Windows/Common/ForwardDecl.h
deleted file mode 100644
index ce2af3ca4111a..0000000000000
--- a/source/Plugins/Process/Windows/Common/ForwardDecl.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- ForwardDecl.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_ForwardDecl_H_
-#define liblldb_Plugins_Process_Windows_ForwardDecl_H_
-
-#include <memory>
-
-// 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.
-};
-
-namespace lldb_private {
-
-class ProcessWindows;
-
-class IDebugDelegate;
-class DebuggerThread;
-class ExceptionRecord;
-
-typedef std::shared_ptr<IDebugDelegate> DebugDelegateSP;
-typedef std::shared_ptr<DebuggerThread> DebuggerThreadSP;
-typedef std::shared_ptr<ExceptionRecord> ExceptionRecordSP;
-typedef std::unique_ptr<ExceptionRecord> ExceptionRecordUP;
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/IDebugDelegate.h b/source/Plugins/Process/Windows/Common/IDebugDelegate.h
deleted file mode 100644
index 73c285f1ecc79..0000000000000
--- a/source/Plugins/Process/Windows/Common/IDebugDelegate.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- IDebugDelegate.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_IDebugDelegate_H_
-#define liblldb_Plugins_Process_Windows_IDebugDelegate_H_
-
-#include "ForwardDecl.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-types.h"
-#include <string>
-
-namespace lldb_private {
-class Status;
-class HostThread;
-
-//----------------------------------------------------------------------
-// IDebugDelegate
-//
-// IDebugDelegate defines an interface which allows implementors to receive
-// notification of events that happen in a debugged process.
-//----------------------------------------------------------------------
-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 Status &error, uint32_t type) = 0;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
deleted file mode 100644
index 92aa7e2678b95..0000000000000
--- a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
+++ /dev/null
@@ -1,73 +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 "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 Status &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/Common/LocalDebugDelegate.h b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
deleted file mode 100644
index 2cb479ccce8ab..0000000000000
--- a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- LocalDebugDelegate.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_LocalDebugDelegate_H_
-#define liblldb_Plugins_Process_Windows_LocalDebugDelegate_H_
-
-#include <memory>
-
-#include "IDebugDelegate.h"
-
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class ProcessWindows;
-typedef std::shared_ptr<ProcessWindows> ProcessWindowsSP;
-
-//----------------------------------------------------------------------
-// LocalDebugDelegate
-//
-// 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
-// additional flexibility provided by this sort of adapter pattern.
-// 2) LLDB holds a shared_ptr to the ProcessWindows, and our driver thread
-// needs access to it as well. To avoid a race condition, we want to make
-// sure that we're also holding onto a shared_ptr.
-// lldb_private::Process supports enable_shared_from_this, but that gives us
-// a ProcessSP (which is exactly what we are trying to decouple from the
-// 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);
-
- 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 Status &error, uint32_t type) override;
-
-private:
- ProcessWindowsSP GetProcessPointer();
-
- lldb::ProcessWP m_process;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/NtStructures.h b/source/Plugins/Process/Windows/Common/NtStructures.h
deleted file mode 100644
index 6826b98c769e7..0000000000000
--- a/source/Plugins/Process/Windows/Common/NtStructures.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- 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_Windows_Common_NtStructures_h_
-#define liblldb_Plugins_Process_Windows_Common_NtStructures_h_
-
-#include "lldb/Host/windows/windows.h"
-
-// 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;
-};
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
deleted file mode 100644
index 3fe5ab7804cba..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ /dev/null
@@ -1,1119 +0,0 @@
-//===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessWindows.h"
-
-// Windows includes
-#include "lldb/Host/windows/windows.h"
-#include <psapi.h>
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Host/FileSystem.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/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/State.h"
-
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/Threading.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 {
-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;
-}
-
-DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
- // We also can process a read / write permissions here, but if the debugger
- // will make later a write into the allocated memory, it will fail. To get
- // around it is possible inside DoWriteMemory to remember memory permissions,
- // allow write, write and restore permissions, but for now we process only
- // the executable permission.
- //
- // TODO: Process permissions other than executable
- if (protect & ePermissionsExecutable)
- return PAGE_EXECUTE_READWRITE;
-
- return PAGE_READWRITE;
-}
-
-} // 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); }
-
- Status 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 llvm::once_flag g_once_flag;
-
- llvm::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() {}
-
-size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Status &error) {
- error.SetErrorString("GetSTDOUT unsupported on Windows");
- return 0;
-}
-
-size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Status &error) {
- error.SetErrorString("GetSTDERR unsupported on Windows");
- return 0;
-}
-
-size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size,
- Status &error) {
- error.SetErrorString("PutSTDIN unsupported on Windows");
- return 0;
-}
-
-//------------------------------------------------------------------------------
-// ProcessInterface protocol.
-
-lldb_private::ConstString ProcessWindows::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ProcessWindows::GetPluginVersion() { return 1; }
-
-Status ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_BREAKPOINTS);
- LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
- bp_site->GetID(), bp_site->GetLoadAddress());
-
- Status error = EnableSoftwareBreakpoint(bp_site);
- if (!error.Success())
- LLDB_LOG(log, "error: {0}", error);
- return error;
-}
-
-Status ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_BREAKPOINTS);
- LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
- bp_site->GetID(), bp_site->GetLoadAddress());
-
- Status error = DisableSoftwareBreakpoint(bp_site);
-
- if (!error.Success())
- LLDB_LOG(log, "error: {0}", error);
- return error;
-}
-
-Status ProcessWindows::DoDetach(bool keep_stopped) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- 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) {
- LLDB_LOG(log, "state = {0}, but there is no active session.",
- private_state);
- return Status();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Status error;
- if (private_state != eStateExited && private_state != eStateDetached) {
- LLDB_LOG(log, "detaching from process {0} while state = {1}.",
- 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 {
- LLDB_LOG(
- log,
- "error: process {0} in state = {1}, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
- private_state);
- }
-
- return error;
-}
-
-Status 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.
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- Status result;
-
- FileSpec working_dir = launch_info.GetWorkingDirectory();
- namespace fs = llvm::sys::fs;
- if (working_dir) {
- FileSystem::Instance().Resolve(working_dir);
- if (!FileSystem::Instance().IsDirectory(working_dir)) {
- result.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return 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());
-
- LLDB_LOG(log, "error: {0}", message);
- return result;
- }
-
- bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
- m_session_data.reset(new ProcessWindowsData(stop_at_entry));
-
- 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()) {
- LLDB_LOG(log, "failed launching '{0}'. {1}",
- launch_info.GetExecutableFile().GetPath(), result);
- return result;
- }
-
- HostProcess process;
- Status error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail()) {
- LLDB_LOG(log, "failed launching '{0}'. {1}",
- launch_info.GetExecutableFile().GetPath(), error);
- return error;
- }
-
- LLDB_LOG(log, "successfully launched '{0}'",
- launch_info.GetExecutableFile().GetPath());
-
- // 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;
-}
-
-Status
-ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
- const ProcessAttachInfo &attach_info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- 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);
- Status error = debugger->DebugAttach(process_id, attach_info);
- if (error.Fail()) {
- LLDB_LOG(
- log,
- "encountered an error occurred initiating the asynchronous attach. {0}",
- error);
- return error;
- }
-
- HostProcess process;
- error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail()) {
- LLDB_LOG(log,
- "encountered an error waiting for the debugger to connect. {0}",
- error);
- return error;
- }
-
- LLDB_LOG(log, "successfully attached to process with pid={0}", 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;
-}
-
-Status ProcessWindows::DoResume() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- llvm::sys::ScopedLock lock(m_mutex);
- Status error;
-
- StateType private_state = GetPrivateState();
- if (private_state == eStateStopped || private_state == eStateCrashed) {
- LLDB_LOG(log, "process {0} is in state {1}. 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);
- }
-
- LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize());
-
- bool failed = false;
- for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
- auto thread = std::static_pointer_cast<TargetThreadWindows>(
- m_thread_list.GetThreadAtIndex(i));
- Status result = thread->DoResume();
- if (result.Fail()) {
- failed = true;
- LLDB_LOG(
- log,
- "Trying to resume thread at index {0}, but failed with error {1}.",
- i, result);
- }
- }
-
- if (failed) {
- error.SetErrorString("ProcessWindows::DoResume failed");
- return error;
- } else {
- SetPrivateState(eStateRunning);
- }
- } else {
- LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
- m_session_data->m_debugger->GetProcess().GetProcessId(),
- GetPrivateState());
- }
- return error;
-}
-
-Status ProcessWindows::DoDestroy() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- 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) {
- LLDB_LOG(log, "warning: state = {0}, but there is no active session.",
- private_state);
- return Status();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Status error;
- if (private_state != eStateExited && private_state != eStateDetached) {
- LLDB_LOG(log, "Shutting down process {0} while state = {1}.",
- 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 {
- LLDB_LOG(log, "cannot destroy process {0} while state = {1}",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
- private_state);
- }
-
- return error;
-}
-
-Status ProcessWindows::DoHalt(bool &caused_stop) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- Status 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);
- LLDB_LOG(log, "DebugBreakProcess failed with error {0}", error);
- }
- }
- return error;
-}
-
-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() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data) {
- LLDB_LOG(log, "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) {
- LLDB_LOG(log,
- "there is no active exception in process {0}. 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())) {
- LLDB_LOG(log,
- "Single-stepped onto a breakpoint in process {0} at "
- "address {1:x} with breakpoint site {2}",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
- site->GetID());
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
- site->GetID());
- stop_thread->SetStopInfo(stop_info);
- } else {
- LLDB_LOG(log, "single stepping thread {0}", 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) {
- LLDB_LOG(log,
- "detected breakpoint in process {0} at address {1:x} with "
- "breakpoint site {2}",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
- site->GetID());
-
- if (site->ValidForThisThread(stop_thread.get())) {
- LLDB_LOG(log,
- "Breakpoint site {0} is valid for this thread ({1:x}), "
- "creating stop info.",
- site->GetID(), stop_thread->GetID());
-
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
- *stop_thread, site->GetID());
- register_context->SetPC(pc);
- } else {
- LLDB_LOG(log,
- "Breakpoint site {0} 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()`.
- LLDB_LOG(log,
- "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);
- LLDB_LOG(log, "{0}", desc_stream.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 FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
- // 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) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_THREAD);
- // 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;
- LLDB_LOGV(log, "Thread {0} was running and is still running.",
- old_thread_id);
- } else {
- LLDB_LOGV(log, "Thread {0} 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;
- LLDB_LOGV(log, "Thread {0} is new since last update.", thread_info.first);
- }
-
- LLDB_LOG(log, "{0} new threads, {1} old threads, {2} 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, Status &error) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data)
- return 0;
-
- LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", 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)) {
- // Reading from the process can fail for a number of reasons - set the
- // error code and make sure that the number of bytes read is set back to 0
- // because in some scenarios the value of bytes_read returned from the API
- // is garbage.
- error.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "reading failed with error: {0}", error);
- bytes_read = 0;
- }
- return bytes_read;
-}
-
-size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
- size_t size, Status &error) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
- LLDB_LOG(log, "attempting to write {0} bytes into address {1:x}", size,
- vm_addr);
-
- if (!m_session_data) {
- LLDB_LOG(log, "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);
- LLDB_LOG(log, "writing failed with error: {0}", error);
- }
- return bytes_written;
-}
-
-lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions,
- Status &error) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
- LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size,
- permissions);
-
- if (!m_session_data) {
- LLDB_LOG(log, "cannot allocate, there is no active debugger connection.");
- error.SetErrorString(
- "cannot allocate, there is no active debugger connection");
- return LLDB_INVALID_ADDRESS;
- }
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- auto protect = ConvertLldbToWinApiProtect(permissions);
- auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect);
- if (!result) {
- error.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "allocating failed with error: {0}", error);
- return LLDB_INVALID_ADDRESS;
- }
-
- return reinterpret_cast<addr_t>(result);
-}
-
-Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) {
- Status result;
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
- LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr);
-
- if (!m_session_data) {
- LLDB_LOG(log, "cannot deallocate, there is no active debugger connection.");
- result.SetErrorString(
- "cannot deallocate, there is no active debugger connection");
- return result;
- }
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (!VirtualFreeEx(handle, reinterpret_cast<LPVOID>(ptr), 0, MEM_RELEASE)) {
- result.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "deallocating failed with error: {0}", result);
- return result;
- }
-
- return result;
-}
-
-Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
- MemoryRegionInfo &info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- Status error;
- llvm::sys::ScopedLock lock(m_mutex);
- info.Clear();
-
- if (!m_session_data) {
- error.SetErrorString(
- "GetMemoryRegionInfo called with no debugging session.");
- LLDB_LOG(log, "error: {0}", error);
- 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.");
- LLDB_LOG(log, "error: {0}", error);
- return error;
- }
-
- LLDB_LOG(log, "getting info for address {0:x}", 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);
- LLDB_LOG(log,
- "VirtualQueryEx returned error {0} while getting memory "
- "region info for address {1:x}",
- error, 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);
- LLDB_LOGV(log,
- "Memory region info for address {0}: readable={1}, "
- "executable={2}, writable={3}",
- vm_addr, info.GetReadable(), info.GetExecutable(),
- 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.
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
-
- TargetSP target = CalculateTarget();
- 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);
-
- // If the process exits before any initial stop then notify the debugger
- // of the error otherwise WaitForDebuggerConnection() will be blocked.
- // An example of this issue is when a process fails to load a dependent DLL.
- if (m_session_data && !m_session_data->m_initial_stop_received) {
- Status error(exit_code, eErrorTypeWin32);
- OnDebuggerError(error, 0);
- }
-}
-
-void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
- DebuggerThreadSP debugger = m_session_data->m_debugger;
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
- 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);
- FileSystem::Instance().Resolve(executable_file);
- ModuleSpec module_spec(executable_file);
- Status error;
- module = GetTarget().GetSharedModule(module_spec, &error);
- if (!module) {
- return;
- }
-
- GetTarget().SetExecutableModule(module, eLoadDependentsNo);
- }
-
- 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) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
- 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) {
- LLDB_LOG(log,
- "Debugger thread reported exception {0:x} at address {1:x}, "
- "but there is no session.",
- record.GetExceptionCode(), record.GetExceptionAddress());
- return ExceptionResult::SendToApplication;
- }
-
- if (!first_chance) {
- // Not any second chance exception is an application crash by definition.
- // It may be an expression evaluation crash.
- SetPrivateState(eStateStopped);
- }
-
- 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) {
- LLDB_LOG(
- log,
- "Hit loader breakpoint at address {0:x}, setting initial stop event.",
- record.GetExceptionAddress());
- m_session_data->m_initial_stop_received = true;
- ::SetEvent(m_session_data->m_initial_stop_event);
- } else {
- LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
- record.GetExceptionAddress());
- }
- SetPrivateState(eStateStopped);
- break;
- case EXCEPTION_SINGLE_STEP:
- result = ExceptionResult::BreakInDebugger;
- SetPrivateState(eStateStopped);
- break;
- default:
- LLDB_LOG(log,
- "Debugger thread reported exception {0:x} at address {1:x} "
- "(first_chance={2})",
- record.GetExceptionCode(), record.GetExceptionAddress(),
- 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 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.
- Status 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 Status &error, uint32_t type) {
- llvm::sys::ScopedLock lock(m_mutex);
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
-
- 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?
- LLDB_LOG(log,
- "Error {0} occurred during debugging. Unexpected behavior "
- "may result. {1}",
- error.GetError(), error);
- } 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);
- LLDB_LOG(
- log,
- "Error {0} occurred launching the process before the initial stop. {1}",
- error.GetError(), error);
- return;
- }
-}
-
-Status ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger,
- HostProcess &process) {
- Status result;
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
- WINDOWS_LOG_BREAKPOINTS);
- LLDB_LOG(log, "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) {
- LLDB_LOG(log, "hit loader breakpoint, returning.");
-
- process = debugger->GetProcess();
- return m_session_data->m_launch_error;
- } else
- return Status(::GetLastError(), eErrorTypeWin32);
-}
-
-// 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::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
deleted file mode 100644
index 00e384f584080..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ /dev/null
@@ -1,121 +0,0 @@
-//===-- ProcessWindows.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_Common_ProcessWindows_H_
-#define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
-
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-forward.h"
-
-#include "llvm/Support/Mutex.h"
-
-#include "IDebugDelegate.h"
-
-namespace lldb_private {
-
-class HostProcess;
-class ProcessWindowsData;
-
-class ProcessWindows : public Process, public IDebugDelegate {
-public:
- //------------------------------------------------------------------
- // Static functions.
- //------------------------------------------------------------------
- static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const FileSpec *);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
-
- ~ProcessWindows();
-
- size_t GetSTDOUT(char *buf, size_t buf_size, Status &error) override;
- size_t GetSTDERR(char *buf, size_t buf_size, Status &error) override;
- size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override;
-
- // lldb_private::Process overrides
- ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
-
- Status EnableBreakpointSite(BreakpointSite *bp_site) override;
- Status DisableBreakpointSite(BreakpointSite *bp_site) override;
-
- Status DoDetach(bool keep_stopped) override;
- Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
- Status DoAttachToProcessWithID(
- lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
- Status DoResume() override;
- Status DoDestroy() override;
- Status 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,
- Status &error) override;
- size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- Status &error) override;
- lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
- Status &error) override;
- Status DoDeallocateMemory(lldb::addr_t ptr) override;
- Status 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 Status &error, uint32_t type) override;
-
-private:
- Status 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_
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
deleted file mode 100644
index 386e9a5816c5f..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===-- ProcessWindowsLog.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessWindowsLog.h"
-
-using namespace lldb_private;
-
-static constexpr Log::Category g_categories[] = {
- {{"break"}, {"log breakpoints"}, WINDOWS_LOG_BREAKPOINTS},
- {{"event"}, {"log low level debugger events"}, WINDOWS_LOG_EVENT},
- {{"exception"}, {"log exception information"}, WINDOWS_LOG_EXCEPTION},
- {{"memory"}, {"log memory reads and writes"}, WINDOWS_LOG_MEMORY},
- {{"process"}, {"log process events and activities"}, WINDOWS_LOG_PROCESS},
- {{"registers"}, {"log register read/writes"}, WINDOWS_LOG_REGISTERS},
- {{"step"}, {"log step related activities"}, WINDOWS_LOG_STEP},
- {{"thread"}, {"log thread events and activities"}, WINDOWS_LOG_THREAD},
-};
-
-Log::Channel ProcessWindowsLog::g_channel(g_categories, WINDOWS_LOG_PROCESS);
-
-void ProcessWindowsLog::Initialize() {
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() { Log::Register("windows", g_channel); });
-}
-
-void ProcessWindowsLog::Terminate() {}
-
-
-
-
-
-
-
-
-
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
deleted file mode 100644
index b7f59c7081431..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- ProcessWindowsLog.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_ProcessWindowsLog_h_
-#define liblldb_ProcessWindowsLog_h_
-
-#include "lldb/Utility/Log.h"
-
-#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
-
-namespace lldb_private {
-class ProcessWindowsLog {
- static Log::Channel g_channel;
-
-public:
- static void Initialize();
- static void Terminate();
-
- static Log *GetLogIfAny(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
-};
-}
-
-#endif // liblldb_ProcessWindowsLog_h_
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
deleted file mode 100644
index 90d43b2cf8284..0000000000000
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-//===-- RegisterContextWindows.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/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-private-types.h"
-
-#include "ProcessWindowsLog.h"
-#include "RegisterContextWindows.h"
-#include "TargetThreadWindows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-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() {}
-
-void RegisterContextWindows::InvalidateAllRegisters() {
- m_context_stale = true;
-}
-
-bool RegisterContextWindows::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
-
- if (!CacheAllRegisterValues())
- return false;
-
- 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));
-
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- if (!::SetThreadContext(
- wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
- &m_context))
- return false;
-
- return true;
-}
-
-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);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- 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::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- return 0;
-}
-
-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::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::HardwareSingleStep(bool enable) { return false; }
-
-bool RegisterContextWindows::CacheAllRegisterValues() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- 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)) {
- LLDB_LOG(
- log,
- "GetThreadContext failed with error {0} while caching register values.",
- ::GetLastError());
- return false;
- }
- LLDB_LOG(log, "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
deleted file mode 100644
index bd09295c2f238..0000000000000
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- RegisterContextWindows.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_RegisterContextWindows_H_
-#define liblldb_RegisterContextWindows_H_
-
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class Thread;
-
-class RegisterContextWindows : public lldb_private::RegisterContext {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindows();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- void InvalidateAllRegisters() 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;
-
- //------------------------------------------------------------------
- // Subclasses can override these functions if desired
- //------------------------------------------------------------------
- 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;
-
-protected:
- virtual bool CacheAllRegisterValues();
-
- CONTEXT m_context;
- bool m_context_stale;
-};
-}
-
-#endif // #ifndef liblldb_RegisterContextWindows_H_
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
deleted file mode 100644
index b121dc7bf15ea..0000000000000
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- TargetThreadWindows.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/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 "lldb/Utility/Log.h"
-#include "lldb/Utility/Logging.h"
-#include "lldb/Utility/State.h"
-
-#include "Plugins/Process/Utility/UnwindLLDB.h"
-#include "ProcessWindows.h"
-#include "ProcessWindowsLog.h"
-#include "TargetThreadWindows.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_thread_reg_ctx_sp(), m_host_thread(thread) {}
-
-TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
-
-void TargetThreadWindows::RefreshStateAfterStop() {
- ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
- SetState(eStateStopped);
- GetRegisterContext()->InvalidateIfNeeded(false);
-}
-
-void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
-
-void TargetThreadWindows::DidStop() {}
-
-RegisterContextSP TargetThreadWindows::GetRegisterContext() {
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
-
- return m_reg_context_sp;
-}
-
-RegisterContextSP
-TargetThreadWindows::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) {
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine()) {
- case llvm::Triple::x86:
-#if defined(_WIN64)
- // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
- LLDB_LOG(log, "This is a Wow64 process, we should create a "
- "RegisterContextWindows_Wow64, but we don't.");
-#else
- m_thread_reg_ctx_sp.reset(
- new RegisterContextWindows_x86(*this, concrete_frame_idx));
-#endif
- break;
- case llvm::Triple::x86_64:
-#if defined(_WIN64)
- m_thread_reg_ctx_sp.reset(
- new RegisterContextWindows_x64(*this, concrete_frame_idx));
-#else
- LLDB_LOG(log, "LLDB is 32-bit, but the target process is 64-bit.");
-#endif
- default:
- break;
- }
- }
- reg_ctx_sp = m_thread_reg_ctx_sp;
- } else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
- }
-
- return reg_ctx_sp;
-}
-
-bool TargetThreadWindows::CalculateStopInfo() {
- SetStopInfo(m_stop_info_sp);
- return true;
-}
-
-Unwind *TargetThreadWindows::GetUnwinder() {
- // FIXME: Implement an unwinder based on the Windows unwinder exposed through
- // DIA SDK.
- if (!m_unwinder_ap)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
- return m_unwinder_ap.get();
-}
-
-Status TargetThreadWindows::DoResume() {
- StateType resume_state = GetTemporaryResumeState();
- StateType current_state = GetState();
- if (resume_state == current_state)
- return Status();
-
- 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 {
- // ResumeThread returns -1 on error, or the thread's *previous* suspend
- // count on success. This means that the return value is 1 when the thread
- // was restarted. Note that DWORD is an unsigned int, so we need to
- // explicitly compare with -1.
- previous_suspend_count = ::ResumeThread(thread_handle);
-
- if (previous_suspend_count == (DWORD)-1)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- } while (previous_suspend_count > 1);
- }
-
- return Status();
-}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
deleted file mode 100644
index 952c0f55b57f3..0000000000000
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- TargetThreadWindows.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_TargetThreadWindows_H_
-#define liblldb_Plugins_Process_Windows_TargetThreadWindows_H_
-
-//#include "ForwardDecl.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/lldb-forward.h"
-
-#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;
- lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(StackFrame *frame) override;
- bool CalculateStopInfo() override;
- Unwind *GetUnwinder() override;
-
- Status DoResume();
-
- HostThread GetHostThread() const { return m_host_thread; }
-
-private:
- lldb::RegisterContextSP m_thread_reg_ctx_sp;
- HostThread m_host_thread;
-};
-} // namespace lldb_private
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
deleted file mode 100644
index 584136a6e5bb4..0000000000000
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-//===-- RegisterContextWindows_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/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-private-types.h"
-
-#include "RegisterContextWindows_x64.h"
-#include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "TargetThreadWindows.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-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 {
-
-// 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,
- eRegisterIndexRbp,
- eRegisterIndexRsp,
- eRegisterIndexR8,
- eRegisterIndexR9,
- eRegisterIndexR10,
- eRegisterIndexR11,
- eRegisterIndexR12,
- eRegisterIndexR13,
- eRegisterIndexR14,
- eRegisterIndexR15,
- eRegisterIndexRip,
- eRegisterIndexRflags
-};
-
-// 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(rax, nullptr),
- {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},
- nullptr,
- nullptr},
- {DEFINE_GPR(rcx, nullptr),
- {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1,
- LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rdx, nullptr),
- {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2,
- 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},
- nullptr,
- nullptr},
- {DEFINE_GPR(rsi, nullptr),
- {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_rsi_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},
- 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},
- nullptr,
- nullptr},
- {DEFINE_GPR(r8, nullptr),
- {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3,
- LLDB_INVALID_REGNUM, lldb_r8_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r9, nullptr),
- {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4,
- LLDB_INVALID_REGNUM, lldb_r9_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r10, nullptr),
- {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5,
- LLDB_INVALID_REGNUM, lldb_r10_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r11, nullptr),
- {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6,
- 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},
- nullptr,
- nullptr},
- {DEFINE_GPR(r13, nullptr),
- {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},
- nullptr,
- nullptr},
- {DEFINE_GPR(r15, nullptr),
- {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_r15_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},
- nullptr,
- nullptr},
- {DEFINE_GPR_BIN(eflags, "flags"),
- {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,
- eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8,
- eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11,
- eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14,
- eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags};
-
-RegisterSet g_register_sets[] = {
- {"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() {}
-
-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;
-}
-
-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];
-}
-
-bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- if (!CacheAllRegisterValues())
- return false;
-
- if (reg_info == nullptr)
- 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 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;
- }
-
- // 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
deleted file mode 100644
index 62cedc8fbab04..0000000000000
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- RegisterContextWindows_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_RegisterContextWindows_x64_H_
-#define liblldb_RegisterContextWindows_x64_H_
-
-#include "RegisterContextWindows.h"
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class Thread;
-
-class RegisterContextWindows_x64 : public RegisterContextWindows {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindows_x64();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- 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;
-};
-}
-
-#endif // #ifndef liblldb_RegisterContextWindows_x64_H_
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
deleted file mode 100644
index e012f9105f31a..0000000000000
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-//===-- RegisterContextWindows_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/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-private-types.h"
-
-#include "ProcessWindowsLog.h"
-#include "RegisterContextWindows_x86.h"
-#include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "TargetThreadWindows.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-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 {
-
-// 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
-};
-
-// 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,
- 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};
-
-RegisterSet g_register_sets[] = {
- {"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() {}
-
-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;
-}
-
-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];
-}
-
-bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- if (!CacheAllRegisterValues())
- return false;
-
- if (reg_info == nullptr)
- 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:
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- LLDB_LOG(log, "Requested unknown register {0}", reg);
- break;
- }
- return false;
-}
-
-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;
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg) {
- case lldb_eax_i386:
- LLDB_LOG(log, "Write value {0:x} to EAX", reg_value.GetAsUInt32());
- m_context.Eax = reg_value.GetAsUInt32();
- break;
- case lldb_ebx_i386:
- LLDB_LOG(log, "Write value {0:x} to EBX", reg_value.GetAsUInt32());
- m_context.Ebx = reg_value.GetAsUInt32();
- break;
- case lldb_ecx_i386:
- LLDB_LOG(log, "Write value {0:x} to ECX", reg_value.GetAsUInt32());
- m_context.Ecx = reg_value.GetAsUInt32();
- break;
- case lldb_edx_i386:
- LLDB_LOG(log, "Write value {0:x} to EDX", reg_value.GetAsUInt32());
- m_context.Edx = reg_value.GetAsUInt32();
- break;
- case lldb_edi_i386:
- LLDB_LOG(log, "Write value {0:x} to EDI", reg_value.GetAsUInt32());
- m_context.Edi = reg_value.GetAsUInt32();
- break;
- case lldb_esi_i386:
- LLDB_LOG(log, "Write value {0:x} to ESI", reg_value.GetAsUInt32());
- m_context.Esi = reg_value.GetAsUInt32();
- break;
- case lldb_ebp_i386:
- LLDB_LOG(log, "Write value {0:x} to EBP", reg_value.GetAsUInt32());
- m_context.Ebp = reg_value.GetAsUInt32();
- break;
- case lldb_esp_i386:
- LLDB_LOG(log, "Write value {0:x} to ESP", reg_value.GetAsUInt32());
- m_context.Esp = reg_value.GetAsUInt32();
- break;
- case lldb_eip_i386:
- LLDB_LOG(log, "Write value {0:x} to EIP", reg_value.GetAsUInt32());
- m_context.Eip = reg_value.GetAsUInt32();
- break;
- case lldb_eflags_i386:
- LLDB_LOG(log, "Write value {0:x} to EFLAGS", reg_value.GetAsUInt32());
- m_context.EFlags = reg_value.GetAsUInt32();
- break;
- default:
- LLDB_LOG(log, "Write value {0:x} to unknown register {1}",
- 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 {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- if ((m_context.ContextFlags & flags_required) != flags_required) {
- LLDB_LOG(log, "Thread context doesn't have {0}", reg_name);
- return false;
- }
- LLDB_LOG(log, "Read value {0:x} from {1}", 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
deleted file mode 100644
index aae645fdb5a3e..0000000000000
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- RegisterContextWindows_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_RegisterContextWindows_x86_H_
-#define liblldb_RegisterContextWindows_x86_H_
-
-#include "RegisterContextWindows.h"
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class Thread;
-
-class RegisterContextWindows_x86 : public RegisterContextWindows {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindows_x86();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- 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;
-
-private:
- 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/elf-core/CMakeLists.txt b/source/Plugins/Process/elf-core/CMakeLists.txt
deleted file mode 100644
index 9b6739824c066..0000000000000
--- a/source/Plugins/Process/elf-core/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-add_lldb_library(lldbPluginProcessElfCore PLUGIN
- ProcessElfCore.cpp
- ThreadElfCore.cpp
- RegisterContextPOSIXCore_arm.cpp
- RegisterContextPOSIXCore_arm64.cpp
- RegisterContextPOSIXCore_mips64.cpp
- RegisterContextPOSIXCore_powerpc.cpp
- RegisterContextPOSIXCore_ppc64le.cpp
- RegisterContextPOSIXCore_s390x.cpp
- RegisterContextPOSIXCore_x86_64.cpp
- RegisterUtilities.cpp
-
- LINK_LIBS
- lldbCore
- lldbTarget
- lldbPluginDynamicLoaderPosixDYLD
- lldbPluginObjectFileELF
- lldbPluginProcessUtility
- LINK_COMPONENTS
- BinaryFormat
- Support
- )
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
deleted file mode 100644
index 4eb5291d54d5a..0000000000000
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- include_directories(${LIBXML2_INCLUDE_DIR})
-endif()
-
-set(LLDB_PLUGINS
- lldbPluginProcessUtility
- lldbPluginPlatformMacOSX
-)
-
-if(HAVE_LIBCOMPRESSION)
- set(LIBCOMPRESSION compression)
-endif()
-
-add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
- GDBRemoteClientBase.cpp
- GDBRemoteCommunication.cpp
- GDBRemoteCommunicationClient.cpp
- GDBRemoteCommunicationHistory.cpp
- GDBRemoteCommunicationReplayServer.cpp
- GDBRemoteCommunicationServer.cpp
- GDBRemoteCommunicationServerCommon.cpp
- GDBRemoteCommunicationServerLLGS.cpp
- GDBRemoteCommunicationServerPlatform.cpp
- GDBRemoteRegisterContext.cpp
- ProcessGDBRemote.cpp
- ProcessGDBRemoteLog.cpp
- ThreadGDBRemote.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbDataFormatters
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- ${LLDB_PLUGINS}
- ${LIBCOMPRESSION}
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/mach-core/CMakeLists.txt b/source/Plugins/Process/mach-core/CMakeLists.txt
deleted file mode 100644
index e79cd82c92a67..0000000000000
--- a/source/Plugins/Process/mach-core/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-add_lldb_library(lldbPluginProcessMachCore PLUGIN
- ProcessMachCore.cpp
- ThreadMachCore.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginDynamicLoaderDarwinKernel
- lldbPluginDynamicLoaderMacOSXDYLD
- lldbPluginObjectFileMachO
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
deleted file mode 100644
index 08b9f08a47f67..0000000000000
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-//===-- ProcessMachCore.cpp ------------------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <stdlib.h>
-
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Threading.h"
-#include <mutex>
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-
-#include "ProcessMachCore.h"
-#include "Plugins/Process/Utility/StopInfoMachException.h"
-#include "ThreadMachCore.h"
-
-// Needed for the plug-in names for the dynamic loaders.
-#include "lldb/Host/SafeMachO.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;
-}
-
-const char *ProcessMachCore::GetPluginDescriptionStatic() {
- return "Mach-O core file debugging plug-in.";
-}
-
-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);
- auto data_sp = FileSystem::Instance().CreateDataBuffer(
- crash_file->GetPath(), header_size, 0);
- 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;
-}
-
-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 && FileSystem::Instance().Exists(m_core_file)) {
- // 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);
- Status 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;
-}
-
-//----------------------------------------------------------------------
-// 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),
- m_dyld_addr(LLDB_INVALID_ADDRESS),
- 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();
-}
-
-//----------------------------------------------------------------------
-// PluginInterface
-//----------------------------------------------------------------------
-ConstString ProcessMachCore::GetPluginName() { return GetPluginNameStatic(); }
-
-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;
- Status 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
-//----------------------------------------------------------------------
-Status ProcessMachCore::DoLoadCore() {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
- LIBLLDB_LOG_PROCESS));
- Status 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;
- }
-
- 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();
- }
-
-
- bool found_main_binary_definitively = false;
-
- addr_t objfile_binary_addr;
- UUID objfile_binary_uuid;
- if (core_objfile->GetCorefileMainBinaryInfo (objfile_binary_addr, objfile_binary_uuid))
- {
- if (objfile_binary_addr != LLDB_INVALID_ADDRESS)
- {
- m_mach_kernel_addr = objfile_binary_addr;
- found_main_binary_definitively = true;
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: using kernel address 0x%" PRIx64
- " from LC_NOTE 'main bin spec' load command.", m_mach_kernel_addr);
- }
- }
-
- // This checks for the presence of an LC_IDENT string in a core file;
- // LC_IDENT is very obsolete and should not be used in new code, but if the
- // load command is present, let's use the contents.
- std::string corefile_identifier = core_objfile->GetIdentifierString();
- if (!found_main_binary_definitively &&
- corefile_identifier.find("Darwin Kernel") != std::string::npos) {
- UUID uuid;
- addr_t addr = LLDB_INVALID_ADDRESS;
- if (corefile_identifier.find("UUID=") != std::string::npos) {
- size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
- std::string uuid_str = corefile_identifier.substr(p, 36);
- uuid.SetFromStringRef(uuid_str);
- }
- if (corefile_identifier.find("stext=") != std::string::npos) {
- size_t p = corefile_identifier.find("stext=") + strlen("stext=");
- if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
- errno = 0;
- addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16);
- if (errno != 0 || addr == 0)
- addr = LLDB_INVALID_ADDRESS;
- }
- }
- if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) {
- m_mach_kernel_addr = addr;
- found_main_binary_definitively = true;
- if (log)
- log->Printf(
- "ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64
- " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'",
- addr, corefile_identifier.c_str());
- }
- }
-
- if (!found_main_binary_definitively &&
- (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 (!found_main_binary_definitively &&
- 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() && 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;
- }
- }
-
- // 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();
- }
- }
-
- 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;
- }
- }
-
- // 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 = Platform::GetAugmentedArchSpec(GetTarget().GetPlatform().get(), "i386");
- }
- 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();
-}
-
-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));
- }
- 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);
-}
-
-Status ProcessMachCore::DoDestroy() { return Status(); }
-
-//------------------------------------------------------------------
-// Process Queries
-//------------------------------------------------------------------
-
-bool ProcessMachCore::IsAlive() { return true; }
-
-bool ProcessMachCore::WarnBeforeDetach() const { return false; }
-
-//------------------------------------------------------------------
-// Process Memory
-//------------------------------------------------------------------
-size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
- Status &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,
- Status &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;
-}
-
-Status 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 Status();
- }
-
- 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 Status();
-}
-
-void ProcessMachCore::Clear() { m_thread_list.Clear(); }
-
-void ProcessMachCore::Initialize() {
- static llvm::once_flag g_once_flag;
-
- llvm::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;
- } 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();
-}
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.h b/source/Plugins/Process/mach-core/ProcessMachCore.h
deleted file mode 100644
index 0c6fc693a50c5..0000000000000
--- a/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- ProcessMachCore.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_ProcessMachCore_h_
-#define liblldb_ProcessMachCore_h_
-
-#include <list>
-#include <vector>
-
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Status.h"
-
-class ThreadKDP;
-
-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::Status DoLoadCore() override;
-
- lldb_private::DynamicLoader *GetDynamicLoader() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- lldb_private::Status 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::Status &error) override;
-
- size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
- lldb_private::Status &error) override;
-
- lldb_private::Status
- 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();
-
-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);
-};
-
-#endif // liblldb_ProcessMachCore_h_
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
deleted file mode 100644
index 16edd28f1a132..0000000000000
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//===-- ThreadMachCore.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ThreadMachCore.h"
-
-#include "lldb/Breakpoint/Watchpoint.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/Utility/ArchSpec.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "ProcessMachCore.h"
-//#include "RegisterContextKDP_arm.h"
-//#include "RegisterContextKDP_i386.h"
-//#include "RegisterContextKDP_x86_64.h"
-
-using namespace lldb;
-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() { DestroyThread(); }
-
-const char *ThreadMachCore::GetName() {
- if (m_thread_name.empty())
- return nullptr;
- 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);
-}
-
-bool ThreadMachCore::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
-
-lldb::RegisterContextSP ThreadMachCore::GetRegisterContext() {
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
- 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 != nullptr)
- 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;
-}
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h
deleted file mode 100644
index 696ba7294e4aa..0000000000000
--- a/source/Plugins/Process/mach-core/ThreadMachCore.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//===-- ThreadMachCore.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_ThreadMachCore_h_
-#define liblldb_ThreadMachCore_h_
-
-#include <string>
-
-#include "lldb/Target/Thread.h"
-
-class ProcessMachCore;
-
-class ThreadMachCore : public lldb_private::Thread {
-public:
- ThreadMachCore(lldb_private::Process &process, lldb::tid_t tid);
-
- ~ThreadMachCore() override;
-
- void RefreshStateAfterStop() override;
-
- const char *GetName() override;
-
- lldb::RegisterContextSP GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- static bool ThreadIDIsValid(lldb::tid_t thread);
-
- bool ShouldStop(bool &step_more);
-
- const char *GetBasicInfoAsString();
-
- 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; }
-
- 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;
-};
-
-#endif // liblldb_ThreadMachCore_h_
diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt
deleted file mode 100644
index 4126a7ea991c2..0000000000000
--- a/source/Plugins/Process/minidump/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-add_lldb_library(lldbPluginProcessMinidump PLUGIN
- MinidumpTypes.cpp
- MinidumpParser.cpp
- RegisterContextMinidump_ARM.cpp
- RegisterContextMinidump_ARM64.cpp
- RegisterContextMinidump_x86_32.cpp
- RegisterContextMinidump_x86_64.cpp
- ProcessMinidump.cpp
- ThreadMinidump.cpp
-
- LINK_LIBS
- lldbCore
- lldbTarget
- lldbUtility
- lldbPluginProcessUtility
- lldbPluginProcessElfCore
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ScriptInterpreter/CMakeLists.txt b/source/Plugins/ScriptInterpreter/CMakeLists.txt
deleted file mode 100644
index 5d8642eb07e67..0000000000000
--- a/source/Plugins/ScriptInterpreter/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_subdirectory(None)
-if (NOT LLDB_DISABLE_PYTHON)
- add_subdirectory(Python)
-endif()
diff --git a/source/Plugins/ScriptInterpreter/None/CMakeLists.txt b/source/Plugins/ScriptInterpreter/None/CMakeLists.txt
deleted file mode 100644
index 7e7dd5896f7c8..0000000000000
--- a/source/Plugins/ScriptInterpreter/None/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-add_lldb_library(lldbPluginScriptInterpreterNone PLUGIN
- ScriptInterpreterNone.cpp
-
- LINK_LIBS
- lldbCore
- lldbInterpreter
- ) \ No newline at end of file
diff --git a/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
deleted file mode 100644
index 56eacc941d64b..0000000000000
--- a/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
- # Call a python script to gather the arch-specific libdir for
- # modules like the lldb module.
- execute_process(
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../scripts/get_relative_lib_dir.py
- RESULT_VARIABLE get_libdir_status
- OUTPUT_VARIABLE relative_libdir
- )
- if (get_libdir_status EQUAL 0)
- add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}")
- endif()
-endif()
-
-add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN
- PythonDataObjects.cpp
- PythonExceptionState.cpp
- ScriptInterpreterPython.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbDataFormatters
- lldbHost
- lldbInterpreter
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/StructuredData/CMakeLists.txt b/source/Plugins/StructuredData/CMakeLists.txt
deleted file mode 100644
index 40d64558482db..0000000000000
--- a/source/Plugins/StructuredData/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-add_subdirectory(DarwinLog)
-
diff --git a/source/Plugins/StructuredData/DarwinLog/CMakeLists.txt b/source/Plugins/StructuredData/DarwinLog/CMakeLists.txt
deleted file mode 100644
index 4df391276c002..0000000000000
--- a/source/Plugins/StructuredData/DarwinLog/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginStructuredDataDarwinLog PLUGIN
- StructuredDataDarwinLog.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbInterpreter
- lldbTarget
- )
diff --git a/source/Plugins/SymbolFile/Breakpad/CMakeLists.txt b/source/Plugins/SymbolFile/Breakpad/CMakeLists.txt
deleted file mode 100644
index e93d0618a0e48..0000000000000
--- a/source/Plugins/SymbolFile/Breakpad/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-add_lldb_library(lldbPluginSymbolFileBreakpad PLUGIN
- SymbolFileBreakpad.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbUtility
- lldbPluginObjectFileBreakpad
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/SymbolFile/CMakeLists.txt b/source/Plugins/SymbolFile/CMakeLists.txt
deleted file mode 100644
index ad1c92bd84698..0000000000000
--- a/source/Plugins/SymbolFile/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-add_subdirectory(Breakpad)
-add_subdirectory(DWARF)
-add_subdirectory(Symtab)
-add_subdirectory(NativePDB)
-add_subdirectory(PDB)
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
deleted file mode 100644
index 0e47ee34fe51b..0000000000000
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
- AppleDWARFIndex.cpp
- DebugNamesDWARFIndex.cpp
- DIERef.cpp
- DWARFAbbreviationDeclaration.cpp
- DWARFASTParserClang.cpp
- DWARFAttribute.cpp
- DWARFBaseDIE.cpp
- DWARFCompileUnit.cpp
- DWARFDataExtractor.cpp
- DWARFDebugAbbrev.cpp
- DWARFDebugAranges.cpp
- DWARFDebugArangeSet.cpp
- DWARFDebugInfo.cpp
- DWARFDebugInfoEntry.cpp
- DWARFDebugLine.cpp
- DWARFDebugMacro.cpp
- DWARFDebugMacinfo.cpp
- DWARFDebugMacinfoEntry.cpp
- DWARFDebugRanges.cpp
- DWARFDeclContext.cpp
- DWARFDefines.cpp
- DWARFDIE.cpp
- DWARFDIECollection.cpp
- DWARFFormValue.cpp
- DWARFIndex.cpp
- DWARFUnit.cpp
- HashedNameToDIE.cpp
- LogChannelDWARF.cpp
- ManualDWARFIndex.cpp
- NameToDIE.cpp
- SymbolFileDWARF.cpp
- SymbolFileDWARFDwo.cpp
- SymbolFileDWARFDwoDwp.cpp
- SymbolFileDWARFDwp.cpp
- SymbolFileDWARFDebugMap.cpp
- UniqueDWARFASTType.cpp
-
- LINK_LIBS
- clangAST
- clangBasic
- lldbCore
- lldbExpression
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginObjCLanguage
- lldbPluginCPlusPlusLanguage
- lldbPluginExpressionParserClang
- LINK_COMPONENTS
- DebugInfoDWARF
- Support
- )
diff --git a/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt b/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt
deleted file mode 100644
index da2d7fe8108aa..0000000000000
--- a/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN
- CompileUnitIndex.cpp
- DWARFLocationExpression.cpp
- PdbAstBuilder.cpp
- PdbIndex.cpp
- PdbSymUid.cpp
- PdbUtil.cpp
- SymbolFileNativePDB.cpp
- UdtRecordCompleter.cpp
-
- LINK_LIBS
- clangAST
- clangLex
- lldbCore
- lldbSymbol
- lldbUtility
- LINK_COMPONENTS
- DebugInfoCodeView
- DebugInfoPDB
- Support
- )
diff --git a/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
deleted file mode 100644
index 19698a7187f71..0000000000000
--- a/source/Plugins/SymbolFile/PDB/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-add_lldb_library(lldbPluginSymbolFilePDB PLUGIN
- PDBASTParser.cpp
- PDBLocationToDWARFExpression.cpp
- SymbolFilePDB.cpp
-
- LINK_LIBS
- clangAST
- clangLex
- lldbCore
- lldbSymbol
- lldbUtility
- lldbPluginSymbolFileNativePDB
- LINK_COMPONENTS
- DebugInfoPDB
- Support
- )
diff --git a/source/Plugins/SymbolFile/Symtab/CMakeLists.txt b/source/Plugins/SymbolFile/Symtab/CMakeLists.txt
deleted file mode 100644
index a2e19bd283f19..0000000000000
--- a/source/Plugins/SymbolFile/Symtab/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-add_lldb_library(lldbPluginSymbolFileSymtab PLUGIN
- SymbolFileSymtab.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- )
diff --git a/source/Plugins/SymbolVendor/CMakeLists.txt b/source/Plugins/SymbolVendor/CMakeLists.txt
deleted file mode 100644
index 94862d5887271..0000000000000
--- a/source/Plugins/SymbolVendor/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- add_subdirectory(MacOSX)
-endif()
-
-add_subdirectory(ELF)
diff --git a/source/Plugins/SymbolVendor/ELF/CMakeLists.txt b/source/Plugins/SymbolVendor/ELF/CMakeLists.txt
deleted file mode 100644
index e742fac931291..0000000000000
--- a/source/Plugins/SymbolVendor/ELF/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_lldb_library(lldbPluginSymbolVendorELF PLUGIN
- SymbolVendorELF.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- )
diff --git a/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt b/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt
deleted file mode 100644
index bbcdff9705aff..0000000000000
--- a/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-include_directories(${LIBXML2_INCLUDE_DIR})
-
-add_lldb_library(lldbPluginSymbolVendorMacOSX PLUGIN
- SymbolVendorMacOSX.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- )
diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
deleted file mode 100644
index 169eed817566b..0000000000000
--- a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-//===-- SymbolVendorMacOSX.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SymbolVendorMacOSX.h"
-
-#include <string.h>
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
-#include "lldb/Host/XML.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// SymbolVendorMacOSX constructor
-//----------------------------------------------------------------------
-SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp)
- : SymbolVendor(module_sp) {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-SymbolVendorMacOSX::~SymbolVendorMacOSX() {}
-
-static bool UUIDsMatch(Module *module, ObjectFile *ofile,
- lldb_private::Stream *feedback_strm) {
- if (module && ofile) {
- // Make sure the UUIDs match
- lldb_private::UUID dsym_uuid;
-
- if (!ofile->GetUUID(&dsym_uuid)) {
- if (feedback_strm) {
- feedback_strm->PutCString(
- "warning: failed to get the uuid for object file: '");
- ofile->GetFileSpec().Dump(feedback_strm);
- feedback_strm->PutCString("\n");
- }
- return false;
- }
-
- if (dsym_uuid == module->GetUUID())
- return true;
-
- // Emit some warning messages since the UUIDs do not match!
- if (feedback_strm) {
- feedback_strm->PutCString(
- "warning: UUID mismatch detected between modules:\n ");
- module->GetUUID().Dump(feedback_strm);
- feedback_strm->PutChar(' ');
- module->GetFileSpec().Dump(feedback_strm);
- feedback_strm->PutCString("\n ");
- dsym_uuid.Dump(feedback_strm);
- feedback_strm->PutChar(' ');
- ofile->GetFileSpec().Dump(feedback_strm);
- feedback_strm->EOL();
- }
- }
- return false;
-}
-
-void SymbolVendorMacOSX::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
-}
-
-void SymbolVendorMacOSX::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString SymbolVendorMacOSX::GetPluginNameStatic() {
- static ConstString g_name("macosx");
- return g_name;
-}
-
-const char *SymbolVendorMacOSX::GetPluginDescriptionStatic() {
- return "Symbol vendor for MacOSX that looks for dSYM files that match "
- "executables.";
-}
-
-//----------------------------------------------------------------------
-// CreateInstance
-//
-// Platforms can register a callback to use when creating symbol vendors to
-// allow for complex debug information file setups, and to also allow for
-// finding separate debug information files.
-//----------------------------------------------------------------------
-SymbolVendor *
-SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
- lldb_private::Stream *feedback_strm) {
- if (!module_sp)
- return NULL;
-
- ObjectFile *obj_file = module_sp->GetObjectFile();
- if (!obj_file)
- return NULL;
-
- static ConstString obj_file_macho("mach-o");
- ConstString obj_name = obj_file->GetPluginName();
- if (obj_name != obj_file_macho)
- return NULL;
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "SymbolVendorMacOSX::CreateInstance (module = %s)",
- module_sp->GetFileSpec().GetPath().c_str());
- SymbolVendorMacOSX *symbol_vendor = new SymbolVendorMacOSX(module_sp);
- if (symbol_vendor) {
- char path[PATH_MAX];
- path[0] = '\0';
-
- // Try and locate the dSYM file on Mac OS X
- static Timer::Category func_cat2(
- "SymbolVendorMacOSX::CreateInstance() locate dSYM");
- Timer scoped_timer2(
- func_cat2,
- "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
- module_sp->GetFileSpec().GetPath().c_str());
-
- // First check to see if the module has a symbol file in mind already. If
- // it does, then we MUST use that.
- FileSpec dsym_fspec(module_sp->GetSymbolFileFileSpec());
-
- ObjectFileSP dsym_objfile_sp;
- if (!dsym_fspec) {
- // No symbol file was specified in the module, lets try and find one
- // ourselves.
- FileSpec file_spec = obj_file->GetFileSpec();
- if (!file_spec)
- file_spec = module_sp->GetFileSpec();
-
- ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
- module_spec.GetUUID() = module_sp->GetUUID();
- dsym_fspec = Symbols::LocateExecutableSymbolFile(module_spec);
- if (module_spec.GetSourceMappingList().GetSize())
- module_sp->GetSourceMappingList().Append(
- module_spec.GetSourceMappingList(), true);
- }
-
- if (dsym_fspec) {
- DataBufferSP dsym_file_data_sp;
- lldb::offset_t dsym_file_data_offset = 0;
- dsym_objfile_sp =
- ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
- FileSystem::Instance().GetByteSize(dsym_fspec),
- dsym_file_data_sp, dsym_file_data_offset);
- if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) {
- // We need a XML parser if we hope to parse a plist...
- if (XMLDocument::XMLEnabled()) {
- char dsym_path[PATH_MAX];
- if (module_sp->GetSourceMappingList().IsEmpty() &&
- dsym_fspec.GetPath(dsym_path, sizeof(dsym_path))) {
- lldb_private::UUID dsym_uuid;
- if (dsym_objfile_sp->GetUUID(&dsym_uuid)) {
- std::string uuid_str = dsym_uuid.GetAsString();
- if (!uuid_str.empty()) {
- char *resources = strstr(dsym_path, "/Contents/Resources/");
- if (resources) {
- char dsym_uuid_plist_path[PATH_MAX];
- resources[strlen("/Contents/Resources/")] = '\0';
- snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path),
- "%s%s.plist", dsym_path, uuid_str.c_str());
- FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path);
- if (FileSystem::Instance().Exists(dsym_uuid_plist_spec)) {
- ApplePropertyList plist(dsym_uuid_plist_path);
- if (plist) {
- std::string DBGBuildSourcePath;
- std::string DBGSourcePath;
-
- // DBGSourcePathRemapping is a dictionary in the plist
- // with keys which are DBGBuildSourcePath file paths and
- // values which are DBGSourcePath file paths
-
- StructuredData::ObjectSP plist_sp =
- plist.GetStructuredData();
- if (plist_sp.get() && plist_sp->GetAsDictionary() &&
- plist_sp->GetAsDictionary()->HasKey(
- "DBGSourcePathRemapping") &&
- plist_sp->GetAsDictionary()
- ->GetValueForKey("DBGSourcePathRemapping")
- ->GetAsDictionary()) {
-
- // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
- // If DBGVersion 2, strip last two components of path remappings from
- // entries to fix an issue with a specific set of
- // DBGSourcePathRemapping entries that lldb worked
- // with.
- // If DBGVersion 3, trust & use the source path remappings as-is.
- //
-
- bool new_style_source_remapping_dictionary = false;
- bool do_truncate_remapping_names = false;
- std::string original_DBGSourcePath_value =
- DBGSourcePath;
- if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) {
- std::string version_string =
- plist_sp->GetAsDictionary()
- ->GetValueForKey("DBGVersion")
- ->GetStringValue("");
- if (!version_string.empty() &&
- isdigit(version_string[0])) {
- int version_number = atoi(version_string.c_str());
- if (version_number > 1) {
- new_style_source_remapping_dictionary = true;
- }
- if (version_number == 2) {
- do_truncate_remapping_names = true;
- }
- }
- }
-
- StructuredData::Dictionary *remappings_dict =
- plist_sp->GetAsDictionary()
- ->GetValueForKey("DBGSourcePathRemapping")
- ->GetAsDictionary();
- remappings_dict->ForEach(
- [&module_sp, new_style_source_remapping_dictionary,
- original_DBGSourcePath_value, do_truncate_remapping_names](
- ConstString key,
- StructuredData::Object *object) -> bool {
- if (object && object->GetAsString()) {
-
- // key is DBGBuildSourcePath
- // object is DBGSourcePath
- std::string DBGSourcePath =
- object->GetStringValue();
- if (!new_style_source_remapping_dictionary &&
- !original_DBGSourcePath_value.empty()) {
- DBGSourcePath = original_DBGSourcePath_value;
- }
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(
- DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(
- resolved_source_path);
- DBGSourcePath =
- resolved_source_path.GetPath();
- }
- module_sp->GetSourceMappingList().Append(
- key, ConstString(DBGSourcePath), true);
- // With version 2 of DBGSourcePathRemapping, we
- // can chop off the last two filename parts
- // from the source remapping and get a more
- // general source remapping that still works.
- // Add this as another option in addition to
- // the full source path remap.
- if (do_truncate_remapping_names) {
- FileSpec build_path(key.AsCString());
- FileSpec source_path(DBGSourcePath.c_str());
- build_path.RemoveLastPathComponent();
- build_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- module_sp->GetSourceMappingList().Append(
- ConstString(build_path.GetPath().c_str()),
- ConstString(source_path.GetPath().c_str()), true);
- }
- }
- return true;
- });
- }
-
- // If we have a DBGBuildSourcePath + DBGSourcePath pair,
- // append those to the source path remappings.
-
- plist.GetValueAsString("DBGBuildSourcePath",
- DBGBuildSourcePath);
- plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
- if (!DBGBuildSourcePath.empty() &&
- !DBGSourcePath.empty()) {
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(resolved_source_path);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_sp->GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath),
- ConstString(DBGSourcePath), true);
- }
- }
- }
- }
- }
- }
- }
- }
-
- symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
- return symbol_vendor;
- }
- }
-
- // Just create our symbol vendor using the current objfile as this is
- // either an executable with no dSYM (that we could locate), an executable
- // with a dSYM that has a UUID that doesn't match.
- symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
- }
- return symbol_vendor;
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-ConstString SymbolVendorMacOSX::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t SymbolVendorMacOSX::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
deleted file mode 100644
index 53b5291af0314..0000000000000
--- a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===-- SymbolVendorMacOSX.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_SymbolVendorMacOSX_h_
-#define liblldb_SymbolVendorMacOSX_h_
-
-#include "lldb/Symbol/SymbolVendor.h"
-#include "lldb/lldb-private.h"
-
-class SymbolVendorMacOSX : public lldb_private::SymbolVendor {
-public:
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::SymbolVendor *
- CreateInstance(const lldb::ModuleSP &module_sp,
- lldb_private::Stream *feedback_strm);
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolVendorMacOSX(const lldb::ModuleSP &module_sp);
-
- virtual ~SymbolVendorMacOSX();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual lldb_private::ConstString GetPluginName();
-
- virtual uint32_t GetPluginVersion();
-
-private:
- DISALLOW_COPY_AND_ASSIGN(SymbolVendorMacOSX);
-};
-
-#endif // liblldb_SymbolVendorMacOSX_h_
diff --git a/source/Plugins/SystemRuntime/CMakeLists.txt b/source/Plugins/SystemRuntime/CMakeLists.txt
deleted file mode 100644
index 0955a9eb74c2d..0000000000000
--- a/source/Plugins/SystemRuntime/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(MacOSX)
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
deleted file mode 100644
index 43e401330c5c5..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-//===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AppleGetItemInfoHandler.h"
-
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Expression/DiagnosticManager.h"
-#include "lldb/Expression/FunctionCaller.h"
-#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-const char *AppleGetItemInfoHandler::g_get_item_info_function_name =
- "__lldb_backtrace_recording_get_item_info";
-const char *AppleGetItemInfoHandler::g_get_item_info_function_code =
- " \n\
-extern \"C\" \n\
-{ \n\
- /* \n\
- * mach defines \n\
- */ \n\
- \n\
- typedef unsigned int uint32_t; \n\
- typedef unsigned long long uint64_t; \n\
- typedef uint32_t mach_port_t; \n\
- typedef mach_port_t vm_map_t; \n\
- typedef int kern_return_t; \n\
- typedef uint64_t mach_vm_address_t; \n\
- typedef uint64_t mach_vm_size_t; \n\
- \n\
- mach_port_t mach_task_self (); \n\
- kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); \n\
- \n\
- /* \n\
- * libBacktraceRecording defines \n\
- */ \n\
- \n\
- typedef uint32_t queue_list_scope_t; \n\
- typedef void *dispatch_queue_t; \n\
- typedef void *introspection_dispatch_queue_info_t; \n\
- typedef void *introspection_dispatch_item_info_ref; \n\
- \n\
- extern uint64_t __introspection_dispatch_queue_item_get_info (introspection_dispatch_item_info_ref item_info_ref, \n\
- introspection_dispatch_item_info_ref *returned_queues_buffer, \n\
- uint64_t *returned_queues_buffer_size); \n\
- extern int printf(const char *format, ...); \n\
- \n\
- /* \n\
- * return type define \n\
- */ \n\
- \n\
- struct get_item_info_return_values \n\
- { \n\
- uint64_t item_info_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */ \n\
- uint64_t item_info_buffer_size; /* the size of the items buffer from libBacktraceRecording */ \n\
- }; \n\
- \n\
- void __lldb_backtrace_recording_get_item_info \n\
- (struct get_item_info_return_values *return_buffer, \n\
- int debug, \n\
- uint64_t /* introspection_dispatch_item_info_ref item_info_ref */ item, \n\
- void *page_to_free, \n\
- uint64_t page_to_free_size) \n\
-{ \n\
- if (debug) \n\
- printf (\"entering get_item_info with args return_buffer == %p, debug == %d, item == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, item, page_to_free, page_to_free_size); \n\
- if (page_to_free != 0) \n\
- { \n\
- mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
- } \n\
- \n\
- __introspection_dispatch_queue_item_get_info ((void*) item, \n\
- (void**)&return_buffer->item_info_buffer_ptr, \n\
- &return_buffer->item_info_buffer_size); \n\
-} \n\
-} \n\
-";
-
-AppleGetItemInfoHandler::AppleGetItemInfoHandler(Process *process)
- : m_process(process), m_get_item_info_impl_code(),
- m_get_item_info_function_mutex(),
- m_get_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_item_info_retbuffer_mutex() {}
-
-AppleGetItemInfoHandler::~AppleGetItemInfoHandler() {}
-
-void AppleGetItemInfoHandler::Detach() {
-
- if (m_process && m_process->IsAlive() &&
- m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) {
- std::unique_lock<std::mutex> lock(m_get_item_info_retbuffer_mutex,
- std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_item_info_return_buffer_addr);
- }
-}
-
-// Compile our __lldb_backtrace_recording_get_item_info() function (from the
-// source above in g_get_item_info_function_code) if we don't find that
-// function in the inferior already with USE_BUILTIN_FUNCTION defined. (e.g.
-// this would be the case for testing.)
-//
-// Insert the __lldb_backtrace_recording_get_item_info into the inferior
-// process if needed.
-//
-// Write the get_item_info_arglist into the inferior's memory space to prepare
-// for the call.
-//
-// Returns the address of the arguments written down in the inferior process,
-// which can be used to make the function call.
-
-lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
- Thread &thread, ValueList &get_item_info_arglist) {
- ExecutionContext exe_ctx(thread.shared_from_this());
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_item_info_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_item_info_function_mutex);
-
- // First stage is to make the UtilityFunction to hold our injected
- // function:
-
- if (!m_get_item_info_impl_code.get()) {
- if (g_get_item_info_function_code != NULL) {
- Status error;
- m_get_item_info_impl_code.reset(
- exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
- g_get_item_info_function_code, eLanguageTypeObjC,
- g_get_item_info_function_name, error));
- if (error.Fail()) {
- if (log)
- log->Printf("Failed to get utility function: %s.",
- error.AsCString());
- return args_addr;
- }
-
- if (!m_get_item_info_impl_code->Install(diagnostics, exe_ctx)) {
- if (log) {
- log->Printf("Failed to install get-item-info introspection.");
- diagnostics.Dump(log);
- }
- m_get_item_info_impl_code.reset();
- return args_addr;
- }
- } else {
- if (log)
- log->Printf("No get-item-info introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Next make the runner function for our implementation utility function.
- Status error;
-
- TypeSystem *type_system =
- thread.GetProcess()->GetTarget().GetScratchTypeSystemForLanguage(
- nullptr, eLanguageTypeC);
- CompilerType get_item_info_return_type =
- type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
-
- get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(
- get_item_info_return_type, get_item_info_arglist,
- thread.shared_from_this(), error);
- if (error.Fail() || get_item_info_caller == nullptr) {
- if (log)
- log->Printf("Error Inserting get-item-info function: \"%s\".",
- error.AsCString());
- return args_addr;
- }
- } else {
- // If it's already made, then we can just retrieve the caller:
- get_item_info_caller = m_get_item_info_impl_code->GetFunctionCaller();
- if (!get_item_info_caller) {
- if (log)
- log->Printf("Failed to get get-item-info introspection caller.");
- m_get_item_info_impl_code.reset();
- return args_addr;
- }
- }
- }
-
- diagnostics.Clear();
-
- // Now write down the argument values for this particular call. This looks
- // like it might be a race condition if other threads were calling into here,
- // but actually it isn't because we allocate a new args structure for this
- // call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_item_info_caller->WriteFunctionArguments(
- exe_ctx, args_addr, get_item_info_arglist, diagnostics)) {
- if (log) {
- log->Printf("Error writing get-item-info function arguments.");
- diagnostics.Dump(log);
- }
-
- return args_addr;
- }
-
- return args_addr;
-}
-
-AppleGetItemInfoHandler::GetItemInfoReturnInfo
-AppleGetItemInfoHandler::GetItemInfo(Thread &thread, uint64_t item,
- addr_t page_to_free,
- uint64_t page_to_free_size,
- Status &error) {
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp(thread.CalculateProcess());
- TargetSP target_sp(thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetItemInfoReturnInfo return_value;
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.item_buffer_size = 0;
-
- error.Clear();
-
- if (!thread.SafeToCallFunctions()) {
- if (log)
- log->Printf("Not safe to call functions on thread 0x%" PRIx64,
- thread.GetID());
- error.SetErrorString("Not safe to call functions on this thread.");
- return return_value;
- }
-
- // Set up the arguments for a call to
-
- // struct get_item_info_return_values
- // {
- // uint64_t item_info_buffer_ptr; /* the address of the items buffer
- // from libBacktraceRecording */
- // uint64_t item_info_buffer_size; /* the size of the items buffer from
- // libBacktraceRecording */
- // };
- //
- // void __lldb_backtrace_recording_get_item_info
- // (struct
- // get_item_info_return_values
- // *return_buffer,
- // int debug,
- // uint64_t item,
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in the inferior process.
-
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType(Value::eValueTypeScalar);
- debug_value.SetCompilerType(clang_int_type);
-
- CompilerType clang_uint64_type =
- clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value item_value;
- item_value.SetValueType(Value::eValueTypeScalar);
- item_value.SetCompilerType(clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType(clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType(clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_item_info_retbuffer_mutex);
- if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS) {
- addr_t bufaddr = process_sp->AllocateMemory(
- 32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Failed to allocate memory for return buffer for get "
- "current queues func call");
- return return_value;
- }
- m_get_item_info_return_buffer_addr = bufaddr;
- }
-
- ValueList argument_values;
-
- return_buffer_ptr_value.GetScalar() = m_get_item_info_return_buffer_addr;
- argument_values.PushValue(return_buffer_ptr_value);
-
- debug_value.GetScalar() = 0;
- argument_values.PushValue(debug_value);
-
- item_value.GetScalar() = item;
- argument_values.PushValue(item_value);
-
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue(page_to_free_value);
-
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue(page_to_free_size_value);
-
- addr_t args_addr = SetupGetItemInfoFunction(thread, argument_values);
-
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetStopOthers(true);
- options.SetTimeout(std::chrono::milliseconds(500));
- options.SetTryAllThreads(false);
- options.SetIsForUtilityExpr(true);
- thread.CalculateExecutionContext(exe_ctx);
-
- if (!m_get_item_info_impl_code) {
- error.SetErrorString("Unable to compile function to call "
- "__introspection_dispatch_queue_item_get_info");
- return return_value;
- }
-
- ExpressionResults func_call_ret;
- Value results;
- FunctionCaller *func_caller = m_get_item_info_impl_code->GetFunctionCaller();
- if (!func_caller) {
- if (log)
- log->Printf("Could not retrieve function caller for "
- "__introspection_dispatch_queue_item_get_info.");
- error.SetErrorString("Could not retrieve function caller for "
- "__introspection_dispatch_queue_item_get_info.");
- return return_value;
- }
-
- func_call_ret = func_caller->ExecuteFunction(exe_ctx, &args_addr, options,
- diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success()) {
- if (log)
- log->Printf("Unable to call "
- "__introspection_dispatch_queue_item_get_info(), got "
- "ExpressionResults %d, error contains %s",
- func_call_ret, error.AsCString(""));
- error.SetErrorString("Unable to call "
- "__introspection_dispatch_queue_get_item_info() for "
- "list of queues");
- return return_value;
- }
-
- return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
- m_get_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() ||
- return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS) {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
- m_get_item_info_return_buffer_addr + 8, 8, 0, error);
-
- if (!error.Success()) {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
- if (log)
- log->Printf("AppleGetItemInfoHandler called "
- "__introspection_dispatch_queue_item_get_info (page_to_free == "
- "0x%" PRIx64 ", size = %" PRId64
- "), returned page is at 0x%" PRIx64 ", size %" PRId64,
- page_to_free, page_to_free_size, return_value.item_buffer_ptr,
- return_value.item_buffer_size);
-
- return return_value;
-}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
deleted file mode 100644
index ac3711ead8783..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- AppleGetItemInfoHandler.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_AppleGetItemInfoHandler_h_
-#define lldb_AppleGetItemInfoHandler_h_
-
-#include <map>
-#include <mutex>
-#include <vector>
-
-#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-public.h"
-
-// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's
-// __introspection_dispatch_queue_item_get_info()
-// function. The function in the inferior will return a struct by value
-// with these members:
-//
-// struct get_item_info_return_values
-// {
-// introspection_dispatch_item_info_ref *item_buffer;
-// uint64_t item_buffer_size;
-// };
-//
-// The item_buffer pointer is an address in the inferior program's address
-// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb.
-//
-// The AppleGetItemInfoHandler object should persist so that the UtilityFunction
-// can be reused multiple times.
-
-namespace lldb_private {
-
-class AppleGetItemInfoHandler {
-public:
- AppleGetItemInfoHandler(lldb_private::Process *process);
-
- ~AppleGetItemInfoHandler();
-
- struct GetItemInfoReturnInfo {
- lldb::addr_t item_buffer_ptr; /* the address of the item buffer from
- libBacktraceRecording */
- lldb::addr_t item_buffer_size; /* the size of the item buffer from
- libBacktraceRecording */
-
- GetItemInfoReturnInfo()
- : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
- };
-
- //----------------------------------------------------------
- /// Get the information about a work item by calling
- /// __introspection_dispatch_queue_item_get_info. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] item
- /// The introspection_dispatch_item_info_ref value for the item of
- /// interest.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be
- /// deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from
- /// any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a
- /// failure of any kind while getting
- /// the information, the item_buffer_ptr value will be
- /// LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetItemInfoReturnInfo GetItemInfo(Thread &thread, lldb::addr_t item,
- lldb::addr_t page_to_free,
- uint64_t page_to_free_size,
- lldb_private::Status &error);
-
- void Detach();
-
-private:
- lldb::addr_t SetupGetItemInfoFunction(Thread &thread,
- ValueList &get_item_info_arglist);
-
- static const char *g_get_item_info_function_name;
- static const char *g_get_item_info_function_code;
-
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
- std::mutex m_get_item_info_function_mutex;
-
- lldb::addr_t m_get_item_info_return_buffer_addr;
- std::mutex m_get_item_info_retbuffer_mutex;
-};
-
-} // using namespace lldb_private
-
-#endif // lldb_AppleGetItemInfoHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
deleted file mode 100644
index 78e50e673af0a..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-//===-- AppleGetPendingItemsHandler.cpp -------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AppleGetPendingItemsHandler.h"
-
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Expression/DiagnosticManager.h"
-#include "lldb/Expression/FunctionCaller.h"
-#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-const char *AppleGetPendingItemsHandler::g_get_pending_items_function_name =
- "__lldb_backtrace_recording_get_pending_items";
-const char *AppleGetPendingItemsHandler::g_get_pending_items_function_code =
- " \n\
-extern \"C\" \n\
-{ \n\
- /* \n\
- * mach defines \n\
- */ \n\
- \n\
- typedef unsigned int uint32_t; \n\
- typedef unsigned long long uint64_t; \n\
- typedef uint32_t mach_port_t; \n\
- typedef mach_port_t vm_map_t; \n\
- typedef int kern_return_t; \n\
- typedef uint64_t mach_vm_address_t; \n\
- typedef uint64_t mach_vm_size_t; \n\
- \n\
- mach_port_t mach_task_self (); \n\
- kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); \n\
- \n\
- /* \n\
- * libBacktraceRecording defines \n\
- */ \n\
- \n\
- typedef uint32_t queue_list_scope_t; \n\
- typedef void *dispatch_queue_t; \n\
- typedef void *introspection_dispatch_queue_info_t; \n\
- typedef void *introspection_dispatch_item_info_ref; \n\
- \n\
- extern uint64_t __introspection_dispatch_queue_get_pending_items (dispatch_queue_t queue, \n\
- introspection_dispatch_item_info_ref *returned_queues_buffer, \n\
- uint64_t *returned_queues_buffer_size); \n\
- extern int printf(const char *format, ...); \n\
- \n\
- /* \n\
- * return type define \n\
- */ \n\
- \n\
- struct get_pending_items_return_values \n\
- { \n\
- uint64_t pending_items_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */ \n\
- uint64_t pending_items_buffer_size; /* the size of the items buffer from libBacktraceRecording */ \n\
- uint64_t count; /* the number of items included in the queues buffer */ \n\
- }; \n\
- \n\
- void __lldb_backtrace_recording_get_pending_items \n\
- (struct get_pending_items_return_values *return_buffer, \n\
- int debug, \n\
- uint64_t /* dispatch_queue_t */ queue, \n\
- void *page_to_free, \n\
- uint64_t page_to_free_size) \n\
-{ \n\
- if (debug) \n\
- printf (\"entering get_pending_items with args return_buffer == %p, debug == %d, queue == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, queue, page_to_free, page_to_free_size); \n\
- if (page_to_free != 0) \n\
- { \n\
- mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
- } \n\
- \n\
- return_buffer->count = __introspection_dispatch_queue_get_pending_items ( \n\
- (void*) queue, \n\
- (void**)&return_buffer->pending_items_buffer_ptr, \n\
- &return_buffer->pending_items_buffer_size); \n\
- if (debug) \n\
- printf(\"result was count %lld\\n\", return_buffer->count); \n\
-} \n\
-} \n\
-";
-
-AppleGetPendingItemsHandler::AppleGetPendingItemsHandler(Process *process)
- : m_process(process), m_get_pending_items_impl_code(),
- m_get_pending_items_function_mutex(),
- m_get_pending_items_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_pending_items_retbuffer_mutex() {}
-
-AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler() {}
-
-void AppleGetPendingItemsHandler::Detach() {
- if (m_process && m_process->IsAlive() &&
- m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS) {
- std::unique_lock<std::mutex> lock(m_get_pending_items_retbuffer_mutex,
- std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_pending_items_return_buffer_addr);
- }
-}
-
-// Compile our __lldb_backtrace_recording_get_pending_items() function (from
-// the source above in g_get_pending_items_function_code) if we don't find that
-// function in the inferior already with USE_BUILTIN_FUNCTION defined. (e.g.
-// this would be the case for testing.)
-//
-// Insert the __lldb_backtrace_recording_get_pending_items into the inferior
-// process if needed.
-//
-// Write the get_pending_items_arglist into the inferior's memory space to
-// prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process,
-// which can be used to make the function call.
-
-lldb::addr_t AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(
- Thread &thread, ValueList &get_pending_items_arglist) {
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx(thread_sp);
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_pending_items_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_pending_items_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_pending_items_impl_code.get()) {
- if (g_get_pending_items_function_code != NULL) {
- Status error;
- m_get_pending_items_impl_code.reset(
- exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
- g_get_pending_items_function_code, eLanguageTypeObjC,
- g_get_pending_items_function_name, error));
- if (error.Fail()) {
- if (log)
- log->Printf("Failed to get UtilityFunction for pending-items "
- "introspection: %s.",
- error.AsCString());
- return args_addr;
- }
-
- if (!m_get_pending_items_impl_code->Install(diagnostics, exe_ctx)) {
- if (log) {
- log->Printf("Failed to install pending-items introspection.");
- diagnostics.Dump(log);
- }
- m_get_pending_items_impl_code.reset();
- return args_addr;
- }
- } else {
- if (log)
- log->Printf("No pending-items introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Next make the runner function for our implementation utility function.
- Status error;
- ClangASTContext *clang_ast_context =
- thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_pending_items_return_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- get_pending_items_caller =
- m_get_pending_items_impl_code->MakeFunctionCaller(
- get_pending_items_return_type, get_pending_items_arglist,
- thread_sp, error);
- if (error.Fail() || get_pending_items_caller == nullptr) {
- if (log)
- log->Printf("Failed to install pending-items introspection function "
- "caller: %s.",
- error.AsCString());
- m_get_pending_items_impl_code.reset();
- return args_addr;
- }
- }
- }
-
- diagnostics.Clear();
-
- if (get_pending_items_caller == nullptr) {
- if (log)
- log->Printf("Failed to get get_pending_items_caller.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Now write down the argument values for this particular call. This looks
- // like it might be a race condition if other threads were calling into here,
- // but actually it isn't because we allocate a new args structure for this
- // call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_pending_items_caller->WriteFunctionArguments(
- exe_ctx, args_addr, get_pending_items_arglist, diagnostics)) {
- if (log) {
- log->Printf("Error writing pending-items function arguments.");
- diagnostics.Dump(log);
- }
-
- return args_addr;
- }
-
- return args_addr;
-}
-
-AppleGetPendingItemsHandler::GetPendingItemsReturnInfo
-AppleGetPendingItemsHandler::GetPendingItems(Thread &thread, addr_t queue,
- addr_t page_to_free,
- uint64_t page_to_free_size,
- Status &error) {
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp(thread.CalculateProcess());
- TargetSP target_sp(thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetPendingItemsReturnInfo return_value;
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.items_buffer_size = 0;
- return_value.count = 0;
-
- error.Clear();
-
- if (!thread.SafeToCallFunctions()) {
- if (log)
- log->Printf("Not safe to call functions on thread 0x%" PRIx64,
- thread.GetID());
- error.SetErrorString("Not safe to call functions on this thread.");
- return return_value;
- }
-
- // Set up the arguments for a call to
-
- // struct get_pending_items_return_values
- // {
- // uint64_t pending_items_buffer_ptr; /* the address of the items
- // buffer from libBacktraceRecording */
- // uint64_t pending_items_buffer_size; /* the size of the items buffer
- // from libBacktraceRecording */
- // uint64_t count; /* the number of items included in the
- // queues buffer */
- // };
- //
- // void __lldb_backtrace_recording_get_pending_items
- // (struct
- // get_pending_items_return_values
- // *return_buffer,
- // int debug,
- // uint64_t /* dispatch_queue_t */
- // queue
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in the inferior process.
-
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType(Value::eValueTypeScalar);
- debug_value.SetCompilerType(clang_int_type);
-
- CompilerType clang_uint64_type =
- clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value queue_value;
- queue_value.SetValueType(Value::eValueTypeScalar);
- queue_value.SetCompilerType(clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType(clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType(clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_pending_items_retbuffer_mutex);
- if (m_get_pending_items_return_buffer_addr == LLDB_INVALID_ADDRESS) {
- addr_t bufaddr = process_sp->AllocateMemory(
- 32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Failed to allocate memory for return buffer for get "
- "current queues func call");
- return return_value;
- }
- m_get_pending_items_return_buffer_addr = bufaddr;
- }
-
- ValueList argument_values;
-
- return_buffer_ptr_value.GetScalar() = m_get_pending_items_return_buffer_addr;
- argument_values.PushValue(return_buffer_ptr_value);
-
- debug_value.GetScalar() = 0;
- argument_values.PushValue(debug_value);
-
- queue_value.GetScalar() = queue;
- argument_values.PushValue(queue_value);
-
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue(page_to_free_value);
-
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue(page_to_free_size_value);
-
- addr_t args_addr = SetupGetPendingItemsFunction(thread, argument_values);
-
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- FunctionCaller *get_pending_items_caller =
- m_get_pending_items_impl_code->GetFunctionCaller();
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetStopOthers(true);
- options.SetTimeout(std::chrono::milliseconds(500));
- options.SetTryAllThreads(false);
- options.SetIsForUtilityExpr(true);
- thread.CalculateExecutionContext(exe_ctx);
-
- if (get_pending_items_caller == NULL) {
- error.SetErrorString("Unable to compile function to call "
- "__introspection_dispatch_queue_get_pending_items");
- return return_value;
- }
-
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_pending_items_caller->ExecuteFunction(
- exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success()) {
- if (log)
- log->Printf("Unable to call "
- "__introspection_dispatch_queue_get_pending_items(), got "
- "ExpressionResults %d, error contains %s",
- func_call_ret, error.AsCString(""));
- error.SetErrorString("Unable to call "
- "__introspection_dispatch_queue_get_pending_items() "
- "for list of queues");
- return return_value;
- }
-
- return_value.items_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
- m_get_pending_items_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() ||
- return_value.items_buffer_ptr == LLDB_INVALID_ADDRESS) {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- return_value.items_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
- m_get_pending_items_return_buffer_addr + 8, 8, 0, error);
-
- if (!error.Success()) {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- return_value.count = m_process->ReadUnsignedIntegerFromMemory(
- m_get_pending_items_return_buffer_addr + 16, 8, 0, error);
- if (!error.Success()) {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- if (log)
- log->Printf("AppleGetPendingItemsHandler called "
- "__introspection_dispatch_queue_get_pending_items "
- "(page_to_free == 0x%" PRIx64 ", size = %" PRId64
- "), returned page is at 0x%" PRIx64 ", size %" PRId64
- ", count = %" PRId64,
- page_to_free, page_to_free_size, return_value.items_buffer_ptr,
- return_value.items_buffer_size, return_value.count);
-
- return return_value;
-}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
deleted file mode 100644
index d35a72c2ff432..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
+++ /dev/null
@@ -1,120 +0,0 @@
-//===-- AppleGetPendingItemsHandler.h ----------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_AppleGetPendingItemsHandler_h_
-#define lldb_AppleGetPendingItemsHandler_h_
-
-#include <map>
-#include <mutex>
-#include <vector>
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-public.h"
-
-// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's
-// __introspection_dispatch_queue_get_pending_items()
-// function. The function in the inferior will return a struct by value
-// with these members:
-//
-// struct get_pending_items_return_values
-// {
-// introspection_dispatch_item_info_ref *items_buffer;
-// uint64_t items_buffer_size;
-// uint64_t count;
-// };
-//
-// The items_buffer pointer is an address in the inferior program's address
-// space (items_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb. count is the number of items that were stored in the buffer.
-//
-// The AppleGetPendingItemsHandler object should persist so that the
-// UtilityFunction
-// can be reused multiple times.
-
-namespace lldb_private {
-
-class AppleGetPendingItemsHandler {
-public:
- AppleGetPendingItemsHandler(lldb_private::Process *process);
-
- ~AppleGetPendingItemsHandler();
-
- struct GetPendingItemsReturnInfo {
- lldb::addr_t items_buffer_ptr; /* the address of the pending items buffer
- from libBacktraceRecording */
- lldb::addr_t
- items_buffer_size; /* the size of the pending items buffer from
- libBacktraceRecording */
- uint64_t count; /* the number of pending items included in the buffer */
-
- GetPendingItemsReturnInfo()
- : items_buffer_ptr(LLDB_INVALID_ADDRESS), items_buffer_size(0),
- count(0) {}
- };
-
- //----------------------------------------------------------
- /// Get the list of pending items for a given queue via a call to
- /// __introspection_dispatch_queue_get_pending_items. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] queue
- /// The dispatch_queue_t value for the queue of interest.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be
- /// deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from
- /// any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a
- /// failure of any kind while getting
- /// the information, the items_buffer_ptr value will be
- /// LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetPendingItemsReturnInfo GetPendingItems(Thread &thread, lldb::addr_t queue,
- lldb::addr_t page_to_free,
- uint64_t page_to_free_size,
- lldb_private::Status &error);
-
- void Detach();
-
-private:
- lldb::addr_t
- SetupGetPendingItemsFunction(Thread &thread,
- ValueList &get_pending_items_arglist);
-
- static const char *g_get_pending_items_function_name;
- static const char *g_get_pending_items_function_code;
-
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
- std::mutex m_get_pending_items_function_mutex;
-
- lldb::addr_t m_get_pending_items_return_buffer_addr;
- std::mutex m_get_pending_items_retbuffer_mutex;
-};
-
-} // using namespace lldb_private
-
-#endif // lldb_AppleGetPendingItemsHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
deleted file mode 100644
index 245ff6742b439..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-//===-- AppleGetQueuesHandler.cpp -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AppleGetQueuesHandler.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Expression/DiagnosticManager.h"
-#include "lldb/Expression/FunctionCaller.h"
-#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-const char *AppleGetQueuesHandler::g_get_current_queues_function_name =
- "__lldb_backtrace_recording_get_current_queues";
-const char *AppleGetQueuesHandler::g_get_current_queues_function_code =
- " \n\
-extern \"C\" \n\
-{ \n\
- /* \n\
- * mach defines \n\
- */ \n\
- \n\
- typedef unsigned int uint32_t; \n\
- typedef unsigned long long uint64_t; \n\
- typedef uint32_t mach_port_t; \n\
- typedef mach_port_t vm_map_t; \n\
- typedef int kern_return_t; \n\
- typedef uint64_t mach_vm_address_t; \n\
- typedef uint64_t mach_vm_size_t; \n\
- \n\
- mach_port_t mach_task_self (); \n\
- kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); \n\
- \n\
- /* \n\
- * libBacktraceRecording defines \n\
- */ \n\
- \n\
- typedef uint32_t queue_list_scope_t; \n\
- typedef void *introspection_dispatch_queue_info_t; \n\
- \n\
- extern uint64_t __introspection_dispatch_get_queues (queue_list_scope_t scope, \n\
- introspection_dispatch_queue_info_t *returned_queues_buffer, \n\
- uint64_t *returned_queues_buffer_size); \n\
- extern int printf(const char *format, ...); \n\
- \n\
- /* \n\
- * return type define \n\
- */ \n\
- \n\
- struct get_current_queues_return_values \n\
- { \n\
- uint64_t queues_buffer_ptr; /* the address of the queues buffer from libBacktraceRecording */ \n\
- uint64_t queues_buffer_size; /* the size of the queues buffer from libBacktraceRecording */ \n\
- uint64_t count; /* the number of queues included in the queues buffer */ \n\
- }; \n\
- \n\
- void __lldb_backtrace_recording_get_current_queues \n\
- (struct get_current_queues_return_values *return_buffer, \n\
- int debug, \n\
- void *page_to_free, \n\
- uint64_t page_to_free_size) \n\
-{ \n\
- if (debug) \n\
- printf (\"entering get_current_queues with args %p, %d, 0x%p, 0x%llx\\n\", return_buffer, debug, page_to_free, page_to_free_size); \n\
- if (page_to_free != 0) \n\
- { \n\
- mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
- } \n\
- \n\
- return_buffer->count = __introspection_dispatch_get_queues ( \n\
- /* QUEUES_WITH_ANY_ITEMS */ 2, \n\
- (void**)&return_buffer->queues_buffer_ptr, \n\
- &return_buffer->queues_buffer_size); \n\
- if (debug) \n\
- printf(\"result was count %lld\\n\", return_buffer->count); \n\
-} \n\
-} \n\
-";
-
-AppleGetQueuesHandler::AppleGetQueuesHandler(Process *process)
- : m_process(process), m_get_queues_impl_code_up(),
- m_get_queues_function_mutex(),
- m_get_queues_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_queues_retbuffer_mutex() {}
-
-AppleGetQueuesHandler::~AppleGetQueuesHandler() {}
-
-void AppleGetQueuesHandler::Detach() {
-
- if (m_process && m_process->IsAlive() &&
- m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS) {
- std::unique_lock<std::mutex> lock(m_get_queues_retbuffer_mutex,
- std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_queues_return_buffer_addr);
- }
-}
-
-// Construct a CompilerType for the structure that
-// g_get_current_queues_function_code will return by value so we can extract
-// the fields after performing the function call. i.e. we are getting this
-// struct returned to us:
-//
-// struct get_current_queues_return_values
-// {
-// introspection_dispatch_queue_info_t *queues_buffer;
-// uint64_t queues_buffer_size;
-// uint64_t count;
-// };
-
-// Compile our __lldb_backtrace_recording_get_current_queues() function (from
-// the source above in g_get_current_queues_function_code) if we don't find
-// that function in the inferior already with USE_BUILTIN_FUNCTION defined.
-// (e.g. this would be the case for testing.)
-//
-// Insert the __lldb_backtrace_recording_get_current_queues into the inferior
-// process if needed.
-//
-// Write the get_queues_arglist into the inferior's memory space to prepare for
-// the call.
-//
-// Returns the address of the arguments written down in the inferior process,
-// which can be used to make the function call.
-
-lldb::addr_t
-AppleGetQueuesHandler::SetupGetQueuesFunction(Thread &thread,
- ValueList &get_queues_arglist) {
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx(thread_sp);
-
- Address impl_code_address;
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
-
- FunctionCaller *get_queues_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_queues_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_queues_impl_code_up.get()) {
- if (g_get_current_queues_function_code != NULL) {
- Status error;
- m_get_queues_impl_code_up.reset(
- exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
- g_get_current_queues_function_code, eLanguageTypeC,
- g_get_current_queues_function_name, error));
- if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to get UtilityFunction for queues introspection: %s.",
- error.AsCString());
- return args_addr;
- }
-
- if (!m_get_queues_impl_code_up->Install(diagnostics, exe_ctx)) {
- if (log) {
- log->Printf("Failed to install queues introspection");
- diagnostics.Dump(log);
- }
- m_get_queues_impl_code_up.reset();
- return args_addr;
- }
- } else {
- if (log) {
- log->Printf("No queues introspection code found.");
- diagnostics.Dump(log);
- }
- return LLDB_INVALID_ADDRESS;
- }
- }
-
- // Next make the runner function for our implementation utility function.
- ClangASTContext *clang_ast_context =
- thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_queues_return_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Status error;
- get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller(
- get_queues_return_type, get_queues_arglist, thread_sp, error);
- if (error.Fail() || get_queues_caller == nullptr) {
- if (log)
- log->Printf(
- "Could not get function caller for get-queues function: %s.",
- error.AsCString());
- return args_addr;
- }
- }
-
- diagnostics.Clear();
-
- // Now write down the argument values for this particular call. This looks
- // like it might be a race condition if other threads were calling into here,
- // but actually it isn't because we allocate a new args structure for this
- // call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_queues_caller->WriteFunctionArguments(
- exe_ctx, args_addr, get_queues_arglist, diagnostics)) {
- if (log) {
- log->Printf("Error writing get-queues function arguments.");
- diagnostics.Dump(log);
- }
- return args_addr;
- }
-
- return args_addr;
-}
-
-AppleGetQueuesHandler::GetQueuesReturnInfo
-AppleGetQueuesHandler::GetCurrentQueues(Thread &thread, addr_t page_to_free,
- uint64_t page_to_free_size,
- Status &error) {
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp(thread.CalculateProcess());
- TargetSP target_sp(thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetQueuesReturnInfo return_value;
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.queues_buffer_size = 0;
- return_value.count = 0;
-
- error.Clear();
-
- if (!thread.SafeToCallFunctions()) {
- if (log)
- log->Printf("Not safe to call functions on thread 0x%" PRIx64,
- thread.GetID());
- error.SetErrorString("Not safe to call functions on this thread.");
- return return_value;
- }
-
- // Set up the arguments for a call to
-
- // struct get_current_queues_return_values
- // {
- // uint64_t queues_buffer_ptr; /* the address of the queues buffer from
- // libBacktraceRecording */
- // uint64_t queues_buffer_size; /* the size of the queues buffer from
- // libBacktraceRecording */
- // uint64_t count; /* the number of queues included in the
- // queues buffer */
- // };
- //
- // void
- // __lldb_backtrace_recording_get_current_queues
- // (struct
- // get_current_queues_return_values
- // *return_buffer,
- // void *page_to_free,
- // uint64_t page_to_free_size);
-
- // Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in the inferior process.
-
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType(Value::eValueTypeScalar);
- debug_value.SetCompilerType(clang_int_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType(clang_void_ptr_type);
-
- CompilerType clang_uint64_type =
- clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType(clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_queues_retbuffer_mutex);
- if (m_get_queues_return_buffer_addr == LLDB_INVALID_ADDRESS) {
- addr_t bufaddr = process_sp->AllocateMemory(
- 32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Failed to allocate memory for return buffer for get "
- "current queues func call");
- return return_value;
- }
- m_get_queues_return_buffer_addr = bufaddr;
- }
-
- ValueList argument_values;
-
- return_buffer_ptr_value.GetScalar() = m_get_queues_return_buffer_addr;
- argument_values.PushValue(return_buffer_ptr_value);
-
- debug_value.GetScalar() = 0;
- argument_values.PushValue(debug_value);
-
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue(page_to_free_value);
-
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue(page_to_free_size_value);
-
- addr_t args_addr = SetupGetQueuesFunction(thread, argument_values);
-
- if (!m_get_queues_impl_code_up) {
- error.SetErrorString(
- "Unable to compile __introspection_dispatch_get_queues.");
- return return_value;
- }
-
- FunctionCaller *get_queues_caller =
- m_get_queues_impl_code_up->GetFunctionCaller();
-
- if (get_queues_caller == NULL) {
- error.SetErrorString(
- "Unable to get caller for call __introspection_dispatch_get_queues");
- return return_value;
- }
-
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetStopOthers(true);
- options.SetTimeout(std::chrono::milliseconds(500));
- options.SetTryAllThreads(false);
- options.SetIsForUtilityExpr(true);
- thread.CalculateExecutionContext(exe_ctx);
-
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_queues_caller->ExecuteFunction(
- exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success()) {
- if (log)
- log->Printf("Unable to call introspection_get_dispatch_queues(), got "
- "ExpressionResults %d, error contains %s",
- func_call_ret, error.AsCString(""));
- error.SetErrorString("Unable to call introspection_get_dispatch_queues() "
- "for list of queues");
- return return_value;
- }
-
- return_value.queues_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
- m_get_queues_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() ||
- return_value.queues_buffer_ptr == LLDB_INVALID_ADDRESS) {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- return_value.queues_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
- m_get_queues_return_buffer_addr + 8, 8, 0, error);
-
- if (!error.Success()) {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- return_value.count = m_process->ReadUnsignedIntegerFromMemory(
- m_get_queues_return_buffer_addr + 16, 8, 0, error);
- if (!error.Success()) {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- if (log)
- log->Printf("AppleGetQueuesHandler called "
- "__introspection_dispatch_get_queues (page_to_free == "
- "0x%" PRIx64 ", size = %" PRId64
- "), returned page is at 0x%" PRIx64 ", size %" PRId64
- ", count = %" PRId64,
- page_to_free, page_to_free_size, return_value.queues_buffer_ptr,
- return_value.queues_buffer_size, return_value.count);
-
- return return_value;
-}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
deleted file mode 100644
index 0d8e4dc64a685..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===-- AppleGetQueuesHandler.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_AppleGetQueuesHandler_h_
-#define lldb_AppleGetQueuesHandler_h_
-
-#include <map>
-#include <mutex>
-#include <vector>
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-public.h"
-
-// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's introspection_get_dispatch_queues()
-// function. The function in the inferior will return a struct by value
-// with these members:
-//
-// struct get_current_queues_return_values
-// {
-// introspection_dispatch_queue_info_t *queues_buffer;
-// uint64_t queues_buffer_size;
-// uint64_t count;
-// };
-//
-// The queues_buffer pointer is an address in the inferior program's address
-// space (queues_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb. count is the number of queues that were stored in the buffer.
-//
-// The AppleGetQueuesHandler object should persist so that the UtilityFunction
-// can be reused multiple times.
-
-namespace lldb_private {
-
-class AppleGetQueuesHandler {
-public:
- AppleGetQueuesHandler(lldb_private::Process *process);
-
- ~AppleGetQueuesHandler();
-
- struct GetQueuesReturnInfo {
- lldb::addr_t queues_buffer_ptr; /* the address of the queues buffer from
- libBacktraceRecording */
- lldb::addr_t queues_buffer_size; /* the size of the queues buffer from
- libBacktraceRecording */
- uint64_t count; /* the number of queues included in the queues buffer */
-
- GetQueuesReturnInfo()
- : queues_buffer_ptr(LLDB_INVALID_ADDRESS), queues_buffer_size(0),
- count(0) {}
- };
-
- //----------------------------------------------------------
- /// Get the list of queues that exist (with any active or pending items) via
- /// a call to introspection_get_dispatch_queues(). If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be
- /// deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from
- /// any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a
- /// failure of any kind while getting
- /// the information, the queues_buffer_ptr value will be
- /// LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetQueuesReturnInfo GetCurrentQueues(Thread &thread,
- lldb::addr_t page_to_free,
- uint64_t page_to_free_size,
- lldb_private::Status &error);
-
- void Detach();
-
-private:
- lldb::addr_t SetupGetQueuesFunction(Thread &thread,
- ValueList &get_queues_arglist);
-
- static const char *g_get_current_queues_function_name;
- static const char *g_get_current_queues_function_code;
-
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
- std::mutex m_get_queues_function_mutex;
-
- lldb::addr_t m_get_queues_return_buffer_addr;
- std::mutex m_get_queues_retbuffer_mutex;
-};
-
-} // using namespace lldb_private
-
-#endif // lldb_AppleGetQueuesHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
deleted file mode 100644
index ede81333a3e67..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AppleGetThreadItemInfoHandler.h"
-
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Expression/DiagnosticManager.h"
-#include "lldb/Expression/Expression.h"
-#include "lldb/Expression/FunctionCaller.h"
-#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/Symbol.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/Utility/ConstString.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/lldb-private.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-const char
- *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_name =
- "__lldb_backtrace_recording_get_thread_item_info";
-const char
- *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_code =
- " \n\
-extern \"C\" \n\
-{ \n\
- /* \n\
- * mach defines \n\
- */ \n\
- \n\
- typedef unsigned int uint32_t; \n\
- typedef unsigned long long uint64_t; \n\
- typedef uint32_t mach_port_t; \n\
- typedef mach_port_t vm_map_t; \n\
- typedef int kern_return_t; \n\
- typedef uint64_t mach_vm_address_t; \n\
- typedef uint64_t mach_vm_size_t; \n\
- \n\
- mach_port_t mach_task_self (); \n\
- kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); \n\
- \n\
- typedef void *pthread_t; \n\
- extern int printf(const char *format, ...); \n\
- extern pthread_t pthread_self(void); \n\
- \n\
- /* \n\
- * libBacktraceRecording defines \n\
- */ \n\
- \n\
- typedef uint32_t queue_list_scope_t; \n\
- typedef void *dispatch_queue_t; \n\
- typedef void *introspection_dispatch_queue_info_t; \n\
- typedef void *introspection_dispatch_item_info_ref; \n\
- \n\
- extern void __introspection_dispatch_thread_get_item_info (uint64_t thread_id, \n\
- introspection_dispatch_item_info_ref *returned_queues_buffer, \n\
- uint64_t *returned_queues_buffer_size); \n\
- \n\
- /* \n\
- * return type define \n\
- */ \n\
- \n\
- struct get_thread_item_info_return_values \n\
- { \n\
- uint64_t item_info_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */ \n\
- uint64_t item_info_buffer_size; /* the size of the items buffer from libBacktraceRecording */ \n\
- }; \n\
- \n\
- void __lldb_backtrace_recording_get_thread_item_info \n\
- (struct get_thread_item_info_return_values *return_buffer, \n\
- int debug, \n\
- uint64_t thread_id, \n\
- void *page_to_free, \n\
- uint64_t page_to_free_size) \n\
-{ \n\
- void *pthread_id = pthread_self (); \n\
- if (debug) \n\
- printf (\"entering get_thread_item_info with args return_buffer == %p, debug == %d, thread id == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, (uint64_t) thread_id, page_to_free, page_to_free_size); \n\
- if (page_to_free != 0) \n\
- { \n\
- mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
- } \n\
- \n\
- __introspection_dispatch_thread_get_item_info (thread_id, \n\
- (void**)&return_buffer->item_info_buffer_ptr, \n\
- &return_buffer->item_info_buffer_size); \n\
-} \n\
-} \n\
-";
-
-AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler(Process *process)
- : m_process(process), m_get_thread_item_info_impl_code(),
- m_get_thread_item_info_function_mutex(),
- m_get_thread_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_thread_item_info_retbuffer_mutex() {}
-
-AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler() {}
-
-void AppleGetThreadItemInfoHandler::Detach() {
-
- if (m_process && m_process->IsAlive() &&
- m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) {
- std::unique_lock<std::mutex> lock(m_get_thread_item_info_retbuffer_mutex,
- std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr);
- }
-}
-
-// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from
-// the source above in g_get_thread_item_info_function_code) if we don't find
-// that function in the inferior already with USE_BUILTIN_FUNCTION defined.
-// (e.g. this would be the case for testing.)
-//
-// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior
-// process if needed.
-//
-// Write the get_thread_item_info_arglist into the inferior's memory space to
-// prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process,
-// which can be used to make the function call.
-
-lldb::addr_t AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction(
- Thread &thread, ValueList &get_thread_item_info_arglist) {
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx(thread_sp);
- Address impl_code_address;
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_thread_item_info_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_thread_item_info_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_thread_item_info_impl_code.get()) {
- Status error;
- if (g_get_thread_item_info_function_code != NULL) {
- m_get_thread_item_info_impl_code.reset(
- exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
- g_get_thread_item_info_function_code, eLanguageTypeC,
- g_get_thread_item_info_function_name, error));
- if (error.Fail()) {
- if (log)
- log->Printf("Failed to get UtilityFunction for "
- "get-thread-item-info introspection: %s.",
- error.AsCString());
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
-
- if (!m_get_thread_item_info_impl_code->Install(diagnostics, exe_ctx)) {
- if (log) {
- log->Printf(
- "Failed to install get-thread-item-info introspection.");
- diagnostics.Dump(log);
- }
-
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
- } else {
- if (log)
- log->Printf("No get-thread-item-info introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Also make the FunctionCaller for this UtilityFunction:
-
- ClangASTContext *clang_ast_context =
- thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_thread_item_info_return_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- get_thread_item_info_caller =
- m_get_thread_item_info_impl_code->MakeFunctionCaller(
- get_thread_item_info_return_type, get_thread_item_info_arglist,
- thread_sp, error);
- if (error.Fail() || get_thread_item_info_caller == nullptr) {
- if (log)
- log->Printf("Failed to install get-thread-item-info introspection "
- "caller: %s.",
- error.AsCString());
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
-
- } else {
- get_thread_item_info_caller =
- m_get_thread_item_info_impl_code->GetFunctionCaller();
- }
- }
-
- diagnostics.Clear();
-
- // Now write down the argument values for this particular call. This looks
- // like it might be a race condition if other threads were calling into here,
- // but actually it isn't because we allocate a new args structure for this
- // call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_thread_item_info_caller->WriteFunctionArguments(
- exe_ctx, args_addr, get_thread_item_info_arglist, diagnostics)) {
- if (log) {
- log->Printf("Error writing get-thread-item-info function arguments");
- diagnostics.Dump(log);
- }
- return args_addr;
- }
-
- return args_addr;
-}
-
-AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo
-AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
- tid_t thread_id,
- addr_t page_to_free,
- uint64_t page_to_free_size,
- Status &error) {
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp(thread.CalculateProcess());
- TargetSP target_sp(thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetThreadItemInfoReturnInfo return_value;
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.item_buffer_size = 0;
-
- error.Clear();
-
- if (!thread.SafeToCallFunctions()) {
- if (log)
- log->Printf("Not safe to call functions on thread 0x%" PRIx64,
- thread.GetID());
- error.SetErrorString("Not safe to call functions on this thread.");
- return return_value;
- }
-
- // Set up the arguments for a call to
-
- // struct get_thread_item_info_return_values {
- // uint64_t item_info_buffer_ptr; /* the address of the items buffer
- // from libBacktraceRecording */
- // uint64_t item_info_buffer_size; /* the size of the items buffer from
- // libBacktraceRecording */
- // };
- //
- // void __lldb_backtrace_recording_get_thread_item_info
- // (struct
- // get_thread_item_info_return_values
- // *return_buffer,
- // int debug,
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory
- // already allocated by lldb in the inferior process.
-
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType(Value::eValueTypeScalar);
- debug_value.SetCompilerType(clang_int_type);
-
- CompilerType clang_uint64_type =
- clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value thread_id_value;
- thread_id_value.SetValueType(Value::eValueTypeScalar);
- thread_id_value.SetCompilerType(clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType(clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType(clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
- if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS) {
- addr_t bufaddr = process_sp->AllocateMemory(
- 32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Failed to allocate memory for return buffer for get "
- "current queues func call");
- return return_value;
- }
- m_get_thread_item_info_return_buffer_addr = bufaddr;
- }
-
- ValueList argument_values;
-
- return_buffer_ptr_value.GetScalar() =
- m_get_thread_item_info_return_buffer_addr;
- argument_values.PushValue(return_buffer_ptr_value);
-
- debug_value.GetScalar() = 0;
- argument_values.PushValue(debug_value);
-
- thread_id_value.GetScalar() = thread_id;
- argument_values.PushValue(thread_id_value);
-
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue(page_to_free_value);
-
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue(page_to_free_size_value);
-
- addr_t args_addr = SetupGetThreadItemInfoFunction(thread, argument_values);
-
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- FunctionCaller *get_thread_item_info_caller = nullptr;
-
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetStopOthers(true);
- options.SetTimeout(std::chrono::milliseconds(500));
- options.SetTryAllThreads(false);
- options.SetIsForUtilityExpr(true);
- thread.CalculateExecutionContext(exe_ctx);
-
- if (!m_get_thread_item_info_impl_code) {
- error.SetErrorString("Unable to compile function to call "
- "__introspection_dispatch_thread_get_item_info");
- return return_value;
- }
-
- get_thread_item_info_caller =
- m_get_thread_item_info_impl_code->GetFunctionCaller();
-
- if (!get_thread_item_info_caller) {
- error.SetErrorString("Unable to compile function caller for "
- "__introspection_dispatch_thread_get_item_info");
- return return_value;
- }
-
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_thread_item_info_caller->ExecuteFunction(
- exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success()) {
- if (log)
- log->Printf("Unable to call "
- "__introspection_dispatch_thread_get_item_info(), got "
- "ExpressionResults %d, error contains %s",
- func_call_ret, error.AsCString(""));
- error.SetErrorString("Unable to call "
- "__introspection_dispatch_thread_get_item_info() for "
- "list of queues");
- return return_value;
- }
-
- return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
- m_get_thread_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS,
- error);
- if (!error.Success() ||
- return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS) {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
- m_get_thread_item_info_return_buffer_addr + 8, 8, 0, error);
-
- if (!error.Success()) {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
-
- if (log)
- log->Printf("AppleGetThreadItemInfoHandler called "
- "__introspection_dispatch_thread_get_item_info (page_to_free "
- "== 0x%" PRIx64 ", size = %" PRId64
- "), returned page is at 0x%" PRIx64 ", size %" PRId64,
- page_to_free, page_to_free_size, return_value.item_buffer_ptr,
- return_value.item_buffer_size);
-
- return return_value;
-}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
deleted file mode 100644
index 47e1961023629..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//===-- AppleGetThreadItemInfoHandler.h ----------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_AppleGetThreadItemInfoHandler_h_
-#define lldb_AppleGetThreadItemInfoHandler_h_
-
-#include <map>
-#include <mutex>
-#include <vector>
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-public.h"
-
-// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's
-// __introspection_dispatch_thread_get_item_info()
-// function. The function in the inferior will return a struct by value
-// with these members:
-//
-// struct get_thread_item_info_return_values
-// {
-// introspection_dispatch_item_info_ref *item_buffer;
-// uint64_t item_buffer_size;
-// };
-//
-// The item_buffer pointer is an address in the inferior program's address
-// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb.
-//
-// The AppleGetThreadItemInfoHandler object should persist so that the
-// UtilityFunction
-// can be reused multiple times.
-
-namespace lldb_private {
-
-class AppleGetThreadItemInfoHandler {
-public:
- AppleGetThreadItemInfoHandler(lldb_private::Process *process);
-
- ~AppleGetThreadItemInfoHandler();
-
- struct GetThreadItemInfoReturnInfo {
- lldb::addr_t item_buffer_ptr; /* the address of the item buffer from
- libBacktraceRecording */
- lldb::addr_t item_buffer_size; /* the size of the item buffer from
- libBacktraceRecording */
-
- GetThreadItemInfoReturnInfo()
- : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
- };
-
- //----------------------------------------------------------
- /// Get the information about a work item by calling
- /// __introspection_dispatch_thread_get_item_info. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread_id
- /// The thread to get the extended backtrace for.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be
- /// deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from
- /// any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a
- /// failure of any kind while getting
- /// the information, the item_buffer_ptr value will be
- /// LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetThreadItemInfoReturnInfo GetThreadItemInfo(Thread &thread,
- lldb::tid_t thread_id,
- lldb::addr_t page_to_free,
- uint64_t page_to_free_size,
- lldb_private::Status &error);
-
- void Detach();
-
-private:
- lldb::addr_t
- SetupGetThreadItemInfoFunction(Thread &thread,
- ValueList &get_thread_item_info_arglist);
-
- static const char *g_get_thread_item_info_function_name;
- static const char *g_get_thread_item_info_function_code;
-
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
- std::mutex m_get_thread_item_info_function_mutex;
-
- lldb::addr_t m_get_thread_item_info_return_buffer_addr;
- std::mutex m_get_thread_item_info_retbuffer_mutex;
-};
-
-} // using namespace lldb_private
-
-#endif // lldb_AppleGetThreadItemInfoHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt b/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt
deleted file mode 100644
index ac5781b98b09c..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-add_lldb_library(lldbPluginSystemRuntimeMacOSX PLUGIN
- AppleGetItemInfoHandler.cpp
- AppleGetPendingItemsHandler.cpp
- AppleGetQueuesHandler.cpp
- AppleGetThreadItemInfoHandler.cpp
- SystemRuntimeMacOSX.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbExpression
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
deleted file mode 100644
index e61f04e489e84..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ /dev/null
@@ -1,1021 +0,0 @@
-//===-- SystemRuntimeMacOSX.cpp ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Plugins/Process/Utility/HistoryThread.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/ProcessStructReader.h"
-#include "lldb/Target/Queue.h"
-#include "lldb/Target/QueueList.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "SystemRuntimeMacOSX.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// Create an instance of this class. This function is filled into the plugin
-// info class that gets handed out by the plugin factory and allows the lldb to
-// instantiate an instance of this class.
-//----------------------------------------------------------------------
-SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
- bool create = false;
- if (!create) {
- create = true;
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module) {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file) {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create) {
- const llvm::Triple &triple_ref =
- process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS()) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
- }
-
- if (create)
- return new SystemRuntimeMacOSX(process);
- return NULL;
-}
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
- : SystemRuntime(process), m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
- m_get_queues_handler(process), m_get_pending_items_handler(process),
- m_get_item_info_handler(process), m_get_thread_item_info_handler(process),
- m_page_to_free(LLDB_INVALID_ADDRESS), m_page_to_free_size(0),
- m_lib_backtrace_recording_info(),
- m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
- m_libdispatch_offsets(),
- m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
- m_libpthread_offsets(), m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
- m_libdispatch_tsd_indexes(),
- m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
- m_libdispatch_voucher_offsets() {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-SystemRuntimeMacOSX::~SystemRuntimeMacOSX() { Clear(true); }
-
-void SystemRuntimeMacOSX::Detach() {
- m_get_queues_handler.Detach();
- m_get_pending_items_handler.Detach();
- m_get_item_info_handler.Detach();
- m_get_thread_item_info_handler.Detach();
-}
-
-//----------------------------------------------------------------------
-// Clear out the state of this class.
-//----------------------------------------------------------------------
-void SystemRuntimeMacOSX::Clear(bool clear_process) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
-
- if (clear_process)
- m_process = NULL;
- m_break_id = LLDB_INVALID_BREAK_ID;
-}
-
-std::string
-SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr) {
- std::string dispatch_queue_name;
- if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
- return "";
-
- ReadLibdispatchOffsets();
- if (m_libdispatch_offsets.IsValid()) {
- // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
- // thread - deref it to get the address of the dispatch_queue_t structure
- // for this thread's queue.
- Status error;
- addr_t dispatch_queue_addr =
- m_process->ReadPointerFromMemory(dispatch_qaddr, error);
- if (error.Success()) {
- if (m_libdispatch_offsets.dqo_version >= 4) {
- // libdispatch versions 4+, pointer to dispatch name is in the queue
- // structure.
- addr_t pointer_to_label_address =
- dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
- addr_t label_addr =
- m_process->ReadPointerFromMemory(pointer_to_label_address, error);
- if (error.Success()) {
- m_process->ReadCStringFromMemory(label_addr, dispatch_queue_name,
- error);
- }
- } else {
- // libdispatch versions 1-3, dispatch name is a fixed width char array
- // in the queue structure.
- addr_t label_addr =
- dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
- dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
- size_t bytes_read =
- m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
- m_libdispatch_offsets.dqo_label_size, error);
- if (bytes_read < m_libdispatch_offsets.dqo_label_size)
- dispatch_queue_name.erase(bytes_read);
- }
- }
- }
- return dispatch_queue_name;
-}
-
-lldb::addr_t SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress(
- addr_t dispatch_qaddr) {
- addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
- Status error;
- libdispatch_queue_t_address =
- m_process->ReadPointerFromMemory(dispatch_qaddr, error);
- if (!error.Success()) {
- libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
- }
- return libdispatch_queue_t_address;
-}
-
-lldb::QueueKind SystemRuntimeMacOSX::GetQueueKind(addr_t dispatch_queue_addr) {
- if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
- return eQueueKindUnknown;
-
- QueueKind kind = eQueueKindUnknown;
- ReadLibdispatchOffsets();
- if (m_libdispatch_offsets.IsValid() &&
- m_libdispatch_offsets.dqo_version >= 4) {
- Status error;
- uint64_t width = m_process->ReadUnsignedIntegerFromMemory(
- dispatch_queue_addr + m_libdispatch_offsets.dqo_width,
- m_libdispatch_offsets.dqo_width_size, 0, error);
- if (error.Success()) {
- if (width == 1) {
- kind = eQueueKindSerial;
- }
- if (width > 1) {
- kind = eQueueKindConcurrent;
- }
- }
- }
- return kind;
-}
-
-void SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints(
- lldb_private::StructuredData::ObjectSP dict_sp) {
- StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
- if (dict) {
- ReadLibpthreadOffsets();
- if (m_libpthread_offsets.IsValid()) {
- dict->AddIntegerItem("plo_pthread_tsd_base_offset",
- m_libpthread_offsets.plo_pthread_tsd_base_offset);
- dict->AddIntegerItem(
- "plo_pthread_tsd_base_address_offset",
- m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
- dict->AddIntegerItem("plo_pthread_tsd_entry_size",
- m_libpthread_offsets.plo_pthread_tsd_entry_size);
- }
-
- ReadLibdispatchTSDIndexes();
- if (m_libdispatch_tsd_indexes.IsValid()) {
- dict->AddIntegerItem("dti_queue_index",
- m_libdispatch_tsd_indexes.dti_queue_index);
- dict->AddIntegerItem("dti_voucher_index",
- m_libdispatch_tsd_indexes.dti_voucher_index);
- dict->AddIntegerItem("dti_qos_class_index",
- m_libdispatch_tsd_indexes.dti_qos_class_index);
- }
- }
-}
-
-bool SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread(ThreadSP thread_sp) {
- if (thread_sp && thread_sp->GetStackFrameCount() > 0 &&
- thread_sp->GetFrameWithConcreteFrameIndex(0)) {
- const SymbolContext sym_ctx(
- thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext(
- eSymbolContextSymbol));
- static ConstString g_select_symbol("__select");
- if (sym_ctx.GetFunctionName() == g_select_symbol) {
- return false;
- }
- }
- return true;
-}
-
-lldb::queue_id_t
-SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
- queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
-
- if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
- return queue_id;
-
- ReadLibdispatchOffsets();
- if (m_libdispatch_offsets.IsValid()) {
- // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
- // thread - deref it to get the address of the dispatch_queue_t structure
- // for this thread's queue.
- Status error;
- uint64_t dispatch_queue_addr =
- m_process->ReadPointerFromMemory(dispatch_qaddr, error);
- if (error.Success()) {
- addr_t serialnum_address =
- dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
- queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory(
- serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
- LLDB_INVALID_QUEUE_ID, error);
- if (error.Success()) {
- queue_id = serialnum;
- }
- }
- }
-
- return queue_id;
-}
-
-void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
- if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_dispatch_queue_offsets_symbol_name(
- "dispatch_queue_offsets");
- const Symbol *dispatch_queue_offsets_symbol = NULL;
-
- // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6
- // ("Snow Leopard")
- ModuleSpec libSystem_module_spec(FileSpec("libSystem.B.dylib"));
- ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
- libSystem_module_spec));
- if (module_sp)
- dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
- g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
-
- // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion")
- // and later
- if (dispatch_queue_offsets_symbol == NULL) {
- ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib"));
- module_sp = m_process->GetTarget().GetImages().FindFirstModule(
- libdispatch_module_spec);
- if (module_sp)
- dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
- g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
- }
- if (dispatch_queue_offsets_symbol)
- m_dispatch_queue_offsets_addr =
- dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
-}
-
-void SystemRuntimeMacOSX::ReadLibdispatchOffsets() {
- if (m_libdispatch_offsets.IsValid())
- return;
-
- ReadLibdispatchOffsetsAddress();
-
- uint8_t memory_buffer[sizeof(struct LibdispatchOffsets)];
- DataExtractor data(memory_buffer, sizeof(memory_buffer),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
-
- Status error;
- if (m_process->ReadMemory(m_dispatch_queue_offsets_addr, memory_buffer,
- sizeof(memory_buffer),
- error) == sizeof(memory_buffer)) {
- lldb::offset_t data_offset = 0;
-
- // The struct LibdispatchOffsets is a series of uint16_t's - extract them
- // all in one big go.
- data.GetU16(&data_offset, &m_libdispatch_offsets.dqo_version,
- sizeof(struct LibdispatchOffsets) / sizeof(uint16_t));
- }
-}
-
-void SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress() {
- if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_libpthread_layout_offsets_symbol_name(
- "pthread_layout_offsets");
- const Symbol *libpthread_layout_offsets_symbol = NULL;
-
- ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib"));
- ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
- libpthread_module_spec));
- if (module_sp) {
- libpthread_layout_offsets_symbol =
- module_sp->FindFirstSymbolWithNameAndType(
- g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
- if (libpthread_layout_offsets_symbol) {
- m_libpthread_layout_offsets_addr =
- libpthread_layout_offsets_symbol->GetLoadAddress(
- &m_process->GetTarget());
- }
- }
-}
-
-void SystemRuntimeMacOSX::ReadLibpthreadOffsets() {
- if (m_libpthread_offsets.IsValid())
- return;
-
- ReadLibpthreadOffsetsAddress();
-
- if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) {
- uint8_t memory_buffer[sizeof(struct LibpthreadOffsets)];
- DataExtractor data(memory_buffer, sizeof(memory_buffer),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
- Status error;
- if (m_process->ReadMemory(m_libpthread_layout_offsets_addr, memory_buffer,
- sizeof(memory_buffer),
- error) == sizeof(memory_buffer)) {
- lldb::offset_t data_offset = 0;
-
- // The struct LibpthreadOffsets is a series of uint16_t's - extract them
- // all in one big go.
- data.GetU16(&data_offset, &m_libpthread_offsets.plo_version,
- sizeof(struct LibpthreadOffsets) / sizeof(uint16_t));
- }
- }
-}
-
-void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress() {
- if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_libdispatch_tsd_indexes_symbol_name(
- "dispatch_tsd_indexes");
- const Symbol *libdispatch_tsd_indexes_symbol = NULL;
-
- ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib"));
- ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
- libpthread_module_spec));
- if (module_sp) {
- libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType(
- g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
- if (libdispatch_tsd_indexes_symbol) {
- m_dispatch_tsd_indexes_addr =
- libdispatch_tsd_indexes_symbol->GetLoadAddress(
- &m_process->GetTarget());
- }
- }
-}
-
-void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
- if (m_libdispatch_tsd_indexes.IsValid())
- return;
-
- ReadLibdispatchTSDIndexesAddress();
-
- if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
-
-// We don't need to check the version number right now, it will be at least 2,
-// but keep this code around to fetch just the version # for the future where
-// we need to fetch alternate versions of the struct.
-#if 0
- uint16_t dti_version = 2;
- Address dti_struct_addr;
- if (m_process->GetTarget().ResolveLoadAddress (m_dispatch_tsd_indexes_addr, dti_struct_addr))
- {
- Status error;
- uint16_t version = m_process->GetTarget().ReadUnsignedIntegerFromMemory (dti_struct_addr, false, 2, UINT16_MAX, error);
- if (error.Success() && dti_version != UINT16_MAX)
- {
- dti_version = version;
- }
- }
-#endif
-
- ClangASTContext *ast_ctx =
- m_process->GetTarget().GetScratchClangASTContext();
- if (ast_ctx->getASTContext() &&
- m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
- CompilerType uint16 =
- ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
- CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
- nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
- clang::TTK_Struct, lldb::eLanguageTypeC);
-
- ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
- ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
- "dti_version", uint16,
- lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
- "dti_queue_index", uint16,
- lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
- "dti_voucher_index", uint16,
- lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
- "dti_qos_class_index", uint16,
- lldb::eAccessPublic, 0);
- ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
-
- ProcessStructReader struct_reader(m_process, m_dispatch_tsd_indexes_addr,
- dispatch_tsd_indexes_s);
-
- m_libdispatch_tsd_indexes.dti_version =
- struct_reader.GetField<uint16_t>(ConstString("dti_version"));
- m_libdispatch_tsd_indexes.dti_queue_index =
- struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
- m_libdispatch_tsd_indexes.dti_voucher_index =
- struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
- m_libdispatch_tsd_indexes.dti_qos_class_index =
- struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
- }
- }
-}
-
-ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread(ThreadSP real_thread,
- ConstString type) {
- ThreadSP originating_thread_sp;
- if (BacktraceRecordingHeadersInitialized() &&
- type == ConstString("libdispatch")) {
- Status error;
-
- // real_thread is either an actual, live thread (in which case we need to
- // call into libBacktraceRecording to find its originator) or it is an
- // extended backtrace itself, in which case we get the token from it and
- // call into libBacktraceRecording to find the originator of that token.
-
- if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS) {
- originating_thread_sp = GetExtendedBacktraceFromItemRef(
- real_thread->GetExtendedBacktraceToken());
- } else {
- ThreadSP cur_thread_sp(
- m_process->GetThreadList().GetExpressionExecutionThread());
- AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret =
- m_get_thread_item_info_handler.GetThreadItemInfo(
- *cur_thread_sp.get(), real_thread->GetID(), m_page_to_free,
- m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 &&
- ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
- ret.item_buffer_size > 0) {
- DataBufferHeap data(ret.item_buffer_size, 0);
- if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
- ret.item_buffer_size, error) &&
- error.Success()) {
- DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer(extractor);
- bool stop_id_is_valid = true;
- if (item.stop_id == 0)
- stop_id_is_valid = false;
- originating_thread_sp.reset(new HistoryThread(
- *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
- item.stop_id, stop_id_is_valid));
- originating_thread_sp->SetExtendedBacktraceToken(
- item.item_that_enqueued_this);
- originating_thread_sp->SetQueueName(
- item.enqueuing_queue_label.c_str());
- originating_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
- // originating_thread_sp->SetThreadName
- // (item.enqueuing_thread_label.c_str());
- }
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
- }
- }
- return originating_thread_sp;
-}
-
-ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref) {
- ThreadSP return_thread_sp;
-
- AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
- ThreadSP cur_thread_sp(
- m_process->GetThreadList().GetExpressionExecutionThread());
- Status error;
- ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
- m_page_to_free, m_page_to_free_size,
- error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
- ret.item_buffer_size > 0) {
- DataBufferHeap data(ret.item_buffer_size, 0);
- if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
- ret.item_buffer_size, error) &&
- error.Success()) {
- DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer(extractor);
- bool stop_id_is_valid = true;
- if (item.stop_id == 0)
- stop_id_is_valid = false;
- return_thread_sp.reset(new HistoryThread(
- *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
- item.stop_id, stop_id_is_valid));
- return_thread_sp->SetExtendedBacktraceToken(item.item_that_enqueued_this);
- return_thread_sp->SetQueueName(item.enqueuing_queue_label.c_str());
- return_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
- // return_thread_sp->SetThreadName
- // (item.enqueuing_thread_label.c_str());
-
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
- }
- return return_thread_sp;
-}
-
-ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem(QueueItemSP queue_item_sp,
- ConstString type) {
- ThreadSP extended_thread_sp;
- if (type != ConstString("libdispatch"))
- return extended_thread_sp;
-
- bool stop_id_is_valid = true;
- if (queue_item_sp->GetStopID() == 0)
- stop_id_is_valid = false;
-
- extended_thread_sp.reset(
- new HistoryThread(*m_process, queue_item_sp->GetEnqueueingThreadID(),
- queue_item_sp->GetEnqueueingBacktrace(),
- queue_item_sp->GetStopID(), stop_id_is_valid));
- extended_thread_sp->SetExtendedBacktraceToken(
- queue_item_sp->GetItemThatEnqueuedThis());
- extended_thread_sp->SetQueueName(queue_item_sp->GetQueueLabel().c_str());
- extended_thread_sp->SetQueueID(queue_item_sp->GetEnqueueingQueueID());
- // extended_thread_sp->SetThreadName
- // (queue_item_sp->GetThreadLabel().c_str());
-
- return extended_thread_sp;
-}
-
-/* Returns true if we were able to get the version / offset information
- * out of libBacktraceRecording. false means we were unable to retrieve
- * this; the queue_info_version field will be 0.
- */
-
-bool SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized() {
- if (m_lib_backtrace_recording_info.queue_info_version != 0)
- return true;
-
- addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
- addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
- addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
- addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
- Target &target = m_process->GetTarget();
-
- static ConstString introspection_dispatch_queue_info_version(
- "__introspection_dispatch_queue_info_version");
- SymbolContextList sc_list;
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
- introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) >
- 0) {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- AddressRange addr_range;
- sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
- queue_info_version_address =
- addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_queue_info_data_offset(
- "__introspection_dispatch_queue_info_data_offset");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
- introspection_dispatch_queue_info_data_offset, eSymbolTypeData,
- sc_list) > 0) {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- AddressRange addr_range;
- sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
- queue_info_data_offset_address =
- addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_item_info_version(
- "__introspection_dispatch_item_info_version");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
- introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) >
- 0) {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- AddressRange addr_range;
- sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
- item_info_version_address =
- addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_item_info_data_offset(
- "__introspection_dispatch_item_info_data_offset");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
- introspection_dispatch_item_info_data_offset, eSymbolTypeData,
- sc_list) > 0) {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- AddressRange addr_range;
- sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
- item_info_data_offset_address =
- addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
-
- if (queue_info_version_address != LLDB_INVALID_ADDRESS &&
- queue_info_data_offset_address != LLDB_INVALID_ADDRESS &&
- item_info_version_address != LLDB_INVALID_ADDRESS &&
- item_info_data_offset_address != LLDB_INVALID_ADDRESS) {
- Status error;
- m_lib_backtrace_recording_info.queue_info_version =
- m_process->ReadUnsignedIntegerFromMemory(queue_info_version_address, 2,
- 0, error);
- if (error.Success()) {
- m_lib_backtrace_recording_info.queue_info_data_offset =
- m_process->ReadUnsignedIntegerFromMemory(
- queue_info_data_offset_address, 2, 0, error);
- if (error.Success()) {
- m_lib_backtrace_recording_info.item_info_version =
- m_process->ReadUnsignedIntegerFromMemory(item_info_version_address,
- 2, 0, error);
- if (error.Success()) {
- m_lib_backtrace_recording_info.item_info_data_offset =
- m_process->ReadUnsignedIntegerFromMemory(
- item_info_data_offset_address, 2, 0, error);
- if (!error.Success()) {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- } else {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- } else {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- }
- }
-
- return m_lib_backtrace_recording_info.queue_info_version != 0;
-}
-
-const std::vector<ConstString> &
-SystemRuntimeMacOSX::GetExtendedBacktraceTypes() {
- if (m_types.size() == 0) {
- m_types.push_back(ConstString("libdispatch"));
- // We could have pthread as another type in the future if we have a way of
- // gathering that information & it's useful to distinguish between them.
- }
- return m_types;
-}
-
-void SystemRuntimeMacOSX::PopulateQueueList(
- lldb_private::QueueList &queue_list) {
- if (BacktraceRecordingHeadersInitialized()) {
- AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
- ThreadSP cur_thread_sp(
- m_process->GetThreadList().GetExpressionExecutionThread());
- if (cur_thread_sp) {
- Status error;
- queue_info_pointer = m_get_queues_handler.GetCurrentQueues(
- *cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (error.Success()) {
-
- if (queue_info_pointer.count > 0 &&
- queue_info_pointer.queues_buffer_size > 0 &&
- queue_info_pointer.queues_buffer_ptr != 0 &&
- queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS) {
- PopulateQueuesUsingLibBTR(queue_info_pointer.queues_buffer_ptr,
- queue_info_pointer.queues_buffer_size,
- queue_info_pointer.count, queue_list);
- }
- }
- }
- }
-
- // We either didn't have libBacktraceRecording (and need to create the queues
- // list based on threads) or we did get the queues list from
- // libBacktraceRecording but some special queues may not be included in its
- // information. This is needed because libBacktraceRecording will only list
- // queues with pending or running items by default - but the magic com.apple
- // .main-thread queue on thread 1 is always around.
-
- for (ThreadSP thread_sp : m_process->Threads()) {
- if (thread_sp->GetAssociatedWithLibdispatchQueue() != eLazyBoolNo) {
- if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) {
- if (queue_list.FindQueueByID(thread_sp->GetQueueID()).get() == NULL) {
- QueueSP queue_sp(new Queue(m_process->shared_from_this(),
- thread_sp->GetQueueID(),
- thread_sp->GetQueueName()));
- if (thread_sp->ThreadHasQueueInformation()) {
- queue_sp->SetKind(thread_sp->GetQueueKind());
- queue_sp->SetLibdispatchQueueAddress(
- thread_sp->GetQueueLibdispatchQueueAddress());
- queue_list.AddQueue(queue_sp);
- } else {
- queue_sp->SetKind(
- GetQueueKind(thread_sp->GetQueueLibdispatchQueueAddress()));
- queue_sp->SetLibdispatchQueueAddress(
- thread_sp->GetQueueLibdispatchQueueAddress());
- queue_list.AddQueue(queue_sp);
- }
- }
- }
- }
- }
-}
-
-// Returns either an array of introspection_dispatch_item_info_ref's for the
-// pending items on a queue or an array introspection_dispatch_item_info_ref's
-// and code addresses for the pending items on a queue. The information about
-// each of these pending items then needs to be fetched individually by passing
-// the ref to libBacktraceRecording.
-
-SystemRuntimeMacOSX::PendingItemsForQueue
-SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) {
- PendingItemsForQueue pending_item_refs;
- AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
- ThreadSP cur_thread_sp(
- m_process->GetThreadList().GetExpressionExecutionThread());
- if (cur_thread_sp) {
- Status error;
- pending_items_pointer = m_get_pending_items_handler.GetPendingItems(
- *cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size,
- error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (error.Success()) {
- if (pending_items_pointer.count > 0 &&
- pending_items_pointer.items_buffer_size > 0 &&
- pending_items_pointer.items_buffer_ptr != 0 &&
- pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) {
- DataBufferHeap data(pending_items_pointer.items_buffer_size, 0);
- if (m_process->ReadMemory(
- pending_items_pointer.items_buffer_ptr, data.GetBytes(),
- pending_items_pointer.items_buffer_size, error)) {
- DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
-
- // We either have an array of
- // void* item_ref
- // (old style) or we have a structure returned which looks like
- //
- // struct introspection_dispatch_pending_item_info_s {
- // void *item_ref;
- // void *function_or_block;
- // };
- //
- // struct introspection_dispatch_pending_items_array_s {
- // uint32_t version;
- // uint32_t size_of_item_info;
- // introspection_dispatch_pending_item_info_s items[];
- // }
-
- offset_t offset = 0;
- int i = 0;
- uint32_t version = extractor.GetU32(&offset);
- if (version == 1) {
- pending_item_refs.new_style = true;
- uint32_t item_size = extractor.GetU32(&offset);
- uint32_t start_of_array_offset = offset;
- while (offset < pending_items_pointer.items_buffer_size &&
- static_cast<size_t>(i) < pending_items_pointer.count) {
- offset = start_of_array_offset + (i * item_size);
- ItemRefAndCodeAddress item;
- item.item_ref = extractor.GetPointer(&offset);
- item.code_address = extractor.GetPointer(&offset);
- pending_item_refs.item_refs_and_code_addresses.push_back(item);
- i++;
- }
- } else {
- offset = 0;
- pending_item_refs.new_style = false;
- while (offset < pending_items_pointer.items_buffer_size &&
- static_cast<size_t>(i) < pending_items_pointer.count) {
- ItemRefAndCodeAddress item;
- item.item_ref = extractor.GetPointer(&offset);
- item.code_address = LLDB_INVALID_ADDRESS;
- pending_item_refs.item_refs_and_code_addresses.push_back(item);
- i++;
- }
- }
- }
- m_page_to_free = pending_items_pointer.items_buffer_ptr;
- m_page_to_free_size = pending_items_pointer.items_buffer_size;
- }
- }
- }
- return pending_item_refs;
-}
-
-void SystemRuntimeMacOSX::PopulatePendingItemsForQueue(Queue *queue) {
- if (BacktraceRecordingHeadersInitialized()) {
- PendingItemsForQueue pending_item_refs =
- GetPendingItemRefsForQueue(queue->GetLibdispatchQueueAddress());
- for (ItemRefAndCodeAddress pending_item :
- pending_item_refs.item_refs_and_code_addresses) {
- Address addr;
- m_process->GetTarget().ResolveLoadAddress(pending_item.code_address,
- addr);
- QueueItemSP queue_item_sp(new QueueItem(queue->shared_from_this(),
- m_process->shared_from_this(),
- pending_item.item_ref, addr));
- queue->PushPendingQueueItem(queue_item_sp);
- }
- }
-}
-
-void SystemRuntimeMacOSX::CompleteQueueItem(QueueItem *queue_item,
- addr_t item_ref) {
- AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
-
- ThreadSP cur_thread_sp(
- m_process->GetThreadList().GetExpressionExecutionThread());
- Status error;
- ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
- m_page_to_free, m_page_to_free_size,
- error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
- ret.item_buffer_size > 0) {
- DataBufferHeap data(ret.item_buffer_size, 0);
- if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
- ret.item_buffer_size, error) &&
- error.Success()) {
- DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer(extractor);
- queue_item->SetItemThatEnqueuedThis(item.item_that_enqueued_this);
- queue_item->SetEnqueueingThreadID(item.enqueuing_thread_id);
- queue_item->SetEnqueueingQueueID(item.enqueuing_queue_serialnum);
- queue_item->SetStopID(item.stop_id);
- queue_item->SetEnqueueingBacktrace(item.enqueuing_callstack);
- queue_item->SetThreadLabel(item.enqueuing_thread_label);
- queue_item->SetQueueLabel(item.enqueuing_queue_label);
- queue_item->SetTargetQueueLabel(item.target_queue_label);
- }
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
-}
-
-void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR(
- lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count,
- lldb_private::QueueList &queue_list) {
- Status error;
- DataBufferHeap data(queues_buffer_size, 0);
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- if (m_process->ReadMemory(queues_buffer, data.GetBytes(), queues_buffer_size,
- error) == queues_buffer_size &&
- error.Success()) {
- // We've read the information out of inferior memory; free it on the next
- // call we make
- m_page_to_free = queues_buffer;
- m_page_to_free_size = queues_buffer_size;
-
- DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
- offset_t offset = 0;
- uint64_t queues_read = 0;
-
- // The information about the queues is stored in this format (v1): typedef
- // struct introspection_dispatch_queue_info_s {
- // uint32_t offset_to_next;
- // dispatch_queue_t queue;
- // uint64_t serialnum; // queue's serialnum in the process, as
- // provided by libdispatch
- // uint32_t running_work_items_count;
- // uint32_t pending_work_items_count;
- //
- // char data[]; // Starting here, we have variable-length data:
- // // char queue_label[];
- // } introspection_dispatch_queue_info_s;
-
- while (queues_read < count && offset < queues_buffer_size) {
- offset_t start_of_this_item = offset;
-
- uint32_t offset_to_next = extractor.GetU32(&offset);
-
- offset += 4; // Skip over the 4 bytes of reserved space
- addr_t queue = extractor.GetPointer(&offset);
- uint64_t serialnum = extractor.GetU64(&offset);
- uint32_t running_work_items_count = extractor.GetU32(&offset);
- uint32_t pending_work_items_count = extractor.GetU32(&offset);
-
- // Read the first field of the variable length data
- offset = start_of_this_item +
- m_lib_backtrace_recording_info.queue_info_data_offset;
- const char *queue_label = extractor.GetCStr(&offset);
- if (queue_label == NULL)
- queue_label = "";
-
- offset_t start_of_next_item = start_of_this_item + offset_to_next;
- offset = start_of_next_item;
-
- if (log)
- log->Printf("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added "
- "queue with dispatch_queue_t 0x%" PRIx64
- ", serial number 0x%" PRIx64
- ", running items %d, pending items %d, name '%s'",
- queue, serialnum, running_work_items_count,
- pending_work_items_count, queue_label);
-
- QueueSP queue_sp(
- new Queue(m_process->shared_from_this(), serialnum, queue_label));
- queue_sp->SetNumRunningWorkItems(running_work_items_count);
- queue_sp->SetNumPendingWorkItems(pending_work_items_count);
- queue_sp->SetLibdispatchQueueAddress(queue);
- queue_sp->SetKind(GetQueueKind(queue));
- queue_list.AddQueue(queue_sp);
- queues_read++;
- }
- }
-}
-
-SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer(
- lldb_private::DataExtractor &extractor) {
- ItemInfo item;
-
- offset_t offset = 0;
-
- item.item_that_enqueued_this = extractor.GetPointer(&offset);
- item.function_or_block = extractor.GetPointer(&offset);
- item.enqueuing_thread_id = extractor.GetU64(&offset);
- item.enqueuing_queue_serialnum = extractor.GetU64(&offset);
- item.target_queue_serialnum = extractor.GetU64(&offset);
- item.enqueuing_callstack_frame_count = extractor.GetU32(&offset);
- item.stop_id = extractor.GetU32(&offset);
-
- offset = m_lib_backtrace_recording_info.item_info_data_offset;
-
- for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) {
- item.enqueuing_callstack.push_back(extractor.GetPointer(&offset));
- }
- item.enqueuing_thread_label = extractor.GetCStr(&offset);
- item.enqueuing_queue_label = extractor.GetCStr(&offset);
- item.target_queue_label = extractor.GetCStr(&offset);
-
- return item;
-}
-
-void SystemRuntimeMacOSX::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
-}
-
-void SystemRuntimeMacOSX::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString SystemRuntimeMacOSX::GetPluginNameStatic() {
- static ConstString g_name("systemruntime-macosx");
- return g_name;
-}
-
-const char *SystemRuntimeMacOSX::GetPluginDescriptionStatic() {
- return "System runtime plugin for Mac OS X native libraries.";
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString SystemRuntimeMacOSX::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t SystemRuntimeMacOSX::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
deleted file mode 100644
index 5fa78cee46406..0000000000000
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
+++ /dev/null
@@ -1,299 +0,0 @@
-//===-- SystemRuntimeMacOSX.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_SystemRuntimeMacOSX_h_
-#define liblldb_SystemRuntimeMacOSX_h_
-
-#include <mutex>
-#include <string>
-#include <vector>
-
-// Other libraries and framework include
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/QueueItem.h"
-#include "lldb/Target/SystemRuntime.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/StructuredData.h"
-#include "lldb/Utility/UUID.h"
-
-#include "AppleGetItemInfoHandler.h"
-#include "AppleGetPendingItemsHandler.h"
-#include "AppleGetQueuesHandler.h"
-#include "AppleGetThreadItemInfoHandler.h"
-
-class SystemRuntimeMacOSX : public lldb_private::SystemRuntime {
-public:
- SystemRuntimeMacOSX(lldb_private::Process *process);
-
- ~SystemRuntimeMacOSX() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::SystemRuntime *
- CreateInstance(lldb_private::Process *process);
-
- //------------------------------------------------------------------
- // instance methods
- //------------------------------------------------------------------
-
- void Clear(bool clear_process);
-
- void Detach() override;
-
- const std::vector<lldb_private::ConstString> &
- GetExtendedBacktraceTypes() override;
-
- lldb::ThreadSP
- GetExtendedBacktraceThread(lldb::ThreadSP thread,
- lldb_private::ConstString type) override;
-
- lldb::ThreadSP
- GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
- lldb_private::ConstString type) override;
-
- lldb::ThreadSP GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref);
-
- void PopulateQueueList(lldb_private::QueueList &queue_list) override;
-
- void PopulateQueuesUsingLibBTR(lldb::addr_t queues_buffer,
- uint64_t queues_buffer_size, uint64_t count,
- lldb_private::QueueList &queue_list);
-
- void PopulatePendingQueuesUsingLibBTR(lldb::addr_t items_buffer,
- uint64_t items_buffer_size,
- uint64_t count,
- lldb_private::Queue *queue);
-
- std::string
- GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
-
- lldb::queue_id_t
- GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
-
- lldb::addr_t GetLibdispatchQueueAddressFromThreadQAddress(
- lldb::addr_t dispatch_qaddr) override;
-
- void PopulatePendingItemsForQueue(lldb_private::Queue *queue) override;
-
- void CompleteQueueItem(lldb_private::QueueItem *queue_item,
- lldb::addr_t item_ref) override;
-
- lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_queue_addr) override;
-
- void AddThreadExtendedInfoPacketHints(
- lldb_private::StructuredData::ObjectSP dict) override;
-
- bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
-protected:
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
-
-private:
- struct libBacktraceRecording_info {
- uint16_t queue_info_version;
- uint16_t queue_info_data_offset;
- uint16_t item_info_version;
- uint16_t item_info_data_offset;
-
- libBacktraceRecording_info()
- : queue_info_version(0), queue_info_data_offset(0),
- item_info_version(0), item_info_data_offset(0) {}
- };
-
- // A structure which reflects the data recorded in the
- // libBacktraceRecording introspection_dispatch_item_info_s.
- struct ItemInfo {
- lldb::addr_t item_that_enqueued_this;
- lldb::addr_t function_or_block;
- uint64_t enqueuing_thread_id;
- uint64_t enqueuing_queue_serialnum;
- uint64_t target_queue_serialnum;
- uint32_t enqueuing_callstack_frame_count;
- uint32_t stop_id;
- std::vector<lldb::addr_t> enqueuing_callstack;
- std::string enqueuing_thread_label;
- std::string enqueuing_queue_label;
- std::string target_queue_label;
- };
-
- // The offsets of different fields of the dispatch_queue_t structure in
- // a thread/queue process.
- // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
- // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot
- // be cached.
- // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value
- // that can be cached.
- struct LibdispatchOffsets {
- uint16_t dqo_version;
- uint16_t dqo_label;
- uint16_t dqo_label_size;
- uint16_t dqo_flags;
- uint16_t dqo_flags_size;
- uint16_t dqo_serialnum;
- uint16_t dqo_serialnum_size;
- uint16_t dqo_width;
- uint16_t dqo_width_size;
- uint16_t dqo_running;
- uint16_t dqo_running_size;
-
- uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X
- // 10.10/iOS 8
- uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS
- // X 10.10/iOS 8
- uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X
- // 10.10/iOS 8
- uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS
- // X 10.10/iOS 8
- uint16_t
- dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X
- // 10.10/iOS 8
-
- LibdispatchOffsets() {
- dqo_version = UINT16_MAX;
- dqo_flags = UINT16_MAX;
- dqo_serialnum = UINT16_MAX;
- dqo_label = UINT16_MAX;
- dqo_width = UINT16_MAX;
- dqo_running = UINT16_MAX;
- dqo_suspend_cnt = UINT16_MAX;
- dqo_target_queue = UINT16_MAX;
- dqo_target_queue = UINT16_MAX;
- dqo_priority = UINT16_MAX;
- }
-
- bool IsValid() { return dqo_version != UINT16_MAX; }
-
- bool LabelIsValid() { return dqo_label != UINT16_MAX; }
- };
-
- struct LibdispatchVoucherOffsets {
- uint16_t vo_version;
- uint16_t vo_activity_ids_count;
- uint16_t vo_activity_ids_count_size;
- uint16_t vo_activity_ids_array;
- uint16_t vo_activity_ids_array_entry_size;
-
- LibdispatchVoucherOffsets()
- : vo_version(UINT16_MAX), vo_activity_ids_count(UINT16_MAX),
- vo_activity_ids_count_size(UINT16_MAX),
- vo_activity_ids_array(UINT16_MAX),
- vo_activity_ids_array_entry_size(UINT16_MAX) {}
-
- bool IsValid() { return vo_version != UINT16_MAX; }
- };
-
- struct LibdispatchTSDIndexes {
- uint16_t dti_version;
- uint64_t dti_queue_index;
- uint64_t dti_voucher_index;
- uint64_t dti_qos_class_index;
-
- LibdispatchTSDIndexes()
- : dti_version(UINT16_MAX), dti_queue_index(UINT64_MAX),
- dti_voucher_index(UINT64_MAX), dti_qos_class_index(UINT64_MAX) {}
-
- bool IsValid() { return dti_version != UINT16_MAX; }
- };
-
- struct LibpthreadOffsets {
- uint16_t plo_version;
- uint16_t plo_pthread_tsd_base_offset;
- uint16_t plo_pthread_tsd_base_address_offset;
- uint16_t plo_pthread_tsd_entry_size;
-
- LibpthreadOffsets()
- : plo_version(UINT16_MAX), plo_pthread_tsd_base_offset(UINT16_MAX),
- plo_pthread_tsd_base_address_offset(UINT16_MAX),
- plo_pthread_tsd_entry_size(UINT16_MAX) {}
-
- bool IsValid() { return plo_version != UINT16_MAX; }
- };
-
- // The libBacktraceRecording function
- // __introspection_dispatch_queue_get_pending_items has
- // two forms. It can either return a simple array of item_refs (void *) size
- // or it can return
- // a header with uint32_t version, a uint32_t size of item, and then an array
- // of item_refs (void*)
- // and code addresses (void*) for all the pending blocks.
-
- struct ItemRefAndCodeAddress {
- lldb::addr_t item_ref;
- lldb::addr_t code_address;
- };
-
- struct PendingItemsForQueue {
- bool new_style; // new-style means both item_refs and code_addresses avail
- // old-style means only item_refs is filled in
- std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses;
- };
-
- bool BacktraceRecordingHeadersInitialized();
-
- void ReadLibdispatchOffsetsAddress();
-
- void ReadLibdispatchOffsets();
-
- void ReadLibpthreadOffsetsAddress();
-
- void ReadLibpthreadOffsets();
-
- void ReadLibdispatchTSDIndexesAddress();
-
- void ReadLibdispatchTSDIndexes();
-
- PendingItemsForQueue GetPendingItemRefsForQueue(lldb::addr_t queue);
-
- ItemInfo ExtractItemInfoFromBuffer(lldb_private::DataExtractor &extractor);
-
- lldb_private::AppleGetQueuesHandler m_get_queues_handler;
- lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler;
- lldb_private::AppleGetItemInfoHandler m_get_item_info_handler;
- lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler;
-
- lldb::addr_t m_page_to_free;
- uint64_t m_page_to_free_size;
- libBacktraceRecording_info m_lib_backtrace_recording_info;
-
- lldb::addr_t m_dispatch_queue_offsets_addr;
- struct LibdispatchOffsets m_libdispatch_offsets;
-
- lldb::addr_t m_libpthread_layout_offsets_addr;
- struct LibpthreadOffsets m_libpthread_offsets;
-
- lldb::addr_t m_dispatch_tsd_indexes_addr;
- struct LibdispatchTSDIndexes m_libdispatch_tsd_indexes;
-
- lldb::addr_t m_dispatch_voucher_offsets_addr;
- struct LibdispatchVoucherOffsets m_libdispatch_voucher_offsets;
-
- DISALLOW_COPY_AND_ASSIGN(SystemRuntimeMacOSX);
-};
-
-#endif // liblldb_SystemRuntimeMacOSX_h_
diff --git a/source/Plugins/UnwindAssembly/CMakeLists.txt b/source/Plugins/UnwindAssembly/CMakeLists.txt
deleted file mode 100644
index 1723a06045804..0000000000000
--- a/source/Plugins/UnwindAssembly/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-add_subdirectory(InstEmulation)
-add_subdirectory(x86)
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/CMakeLists.txt b/source/Plugins/UnwindAssembly/InstEmulation/CMakeLists.txt
deleted file mode 100644
index 7b7fd721f8505..0000000000000
--- a/source/Plugins/UnwindAssembly/InstEmulation/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_lldb_library(lldbPluginUnwindAssemblyInstEmulation PLUGIN
- UnwindAssemblyInstEmulation.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- )
diff --git a/source/Plugins/UnwindAssembly/x86/CMakeLists.txt b/source/Plugins/UnwindAssembly/x86/CMakeLists.txt
deleted file mode 100644
index 425ae11909923..0000000000000
--- a/source/Plugins/UnwindAssembly/x86/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-add_lldb_library(lldbPluginUnwindAssemblyX86 PLUGIN
- UnwindAssembly-x86.cpp
- x86AssemblyInspectionEngine.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- MC
- MCDisassembler
- )