aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp58
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp45
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h40
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp77
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h99
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp36
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h31
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h38
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp72
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h101
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp75
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp106
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp38
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h49
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp1049
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h133
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp25
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp42
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp109
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp98
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp24
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp111
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp24
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp200
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h53
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp149
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h36
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp207
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h39
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp190
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h23
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h306
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h360
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp77
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp80
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h23
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp84
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h40
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp987
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h162
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp24
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp64
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp1007
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h46
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp33
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp267
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp313
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h119
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp101
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp48
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h56
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp230
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h22
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp306
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h66
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp36
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp123
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h43
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp56
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h32
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp40
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp304
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp75
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp98
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp171
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h31
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h60
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp224
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h179
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp133
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h69
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp74
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h72
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp134
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h69
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp100
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h50
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp333
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h121
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td72
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp50
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h28
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp66
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h56
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp53
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h42
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp282
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h6
301 files changed, 8423 insertions, 4766 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
index d36aeca21c69..505c7d416a82 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
@@ -13,6 +13,7 @@
#include "ABISysV_arm64.h"
#include "Utility/ARM64_DWARF_Registers.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
LLDB_PLUGIN_DEFINE(ABIAArch64)
@@ -30,6 +31,18 @@ void ABIAArch64::Terminate() {
#endif // LLDB_ENABLE_ALL
}
+lldb::addr_t ABIAArch64::FixCodeAddress(lldb::addr_t pc) {
+ if (lldb::ProcessSP process_sp = GetProcessSP())
+ return FixAddress(pc, process_sp->GetCodeAddressMask());
+ return pc;
+}
+
+lldb::addr_t ABIAArch64::FixDataAddress(lldb::addr_t pc) {
+ if (lldb::ProcessSP process_sp = GetProcessSP())
+ return FixAddress(pc, process_sp->GetDataAddressMask());
+ return pc;
+}
+
std::pair<uint32_t, uint32_t>
ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) {
if (name == "pc")
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
index bdff648f1b52..41bbf5cfdeb9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
@@ -16,7 +16,14 @@ public:
static void Initialize();
static void Terminate();
+ virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
+ virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
+
protected:
+ virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) {
+ return pc;
+ }
+
std::pair<uint32_t, uint32_t>
GetEHAndDWARFNums(llvm::StringRef name) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
index 09b319a84a08..348a081cfe17 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -66,7 +66,7 @@ bool ABIMacOSX_arm64::PrepareTrivialCall(
if (log) {
StreamString s;
- s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
+ s.Printf("ABIMacOSX_arm64::PrepareTrivialCall (tid = 0x%" PRIx64
", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
", return_addr = 0x%" PRIx64,
thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
@@ -86,7 +86,7 @@ bool ABIMacOSX_arm64::PrepareTrivialCall(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
// x0 - x7 contain first 8 simple args
- if (args.size() > 8) // TODO handle more than 6 arguments
+ if (args.size() > 8) // TODO handle more than 8 arguments
return false;
for (size_t i = 0; i < args.size(); ++i) {
@@ -384,6 +384,7 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
@@ -654,7 +655,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
bool success = false;
if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
@@ -814,6 +815,11 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
return return_valobj_sp;
}
+lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
+ lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+ return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
+}
+
void ABIMacOSX_arm64::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
CreateInstance);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
index fc8ccee92e71..dc3ab35115fd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
@@ -62,6 +62,8 @@ public:
return true;
}
+ lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
+
// Static Functions
static void Initialize();
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
index 1214195dcfc0..16fb38e107c3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -356,6 +356,7 @@ bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
@@ -622,7 +623,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
bool success = false;
if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
@@ -781,6 +782,61 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
return return_valobj_sp;
}
+lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t mask) {
+ lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+ return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
+}
+
+// Reads code or data address mask for the current Linux process.
+static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp,
+ llvm::StringRef reg_name) {
+ // Linux configures user-space virtual addresses with top byte ignored.
+ // We set default value of mask such that top byte is masked out.
+ uint64_t address_mask = ~((1ULL << 56) - 1);
+ // If Pointer Authentication feature is enabled then Linux exposes
+ // PAC data and code mask register. Try reading relevant register
+ // below and merge it with default address mask calculated above.
+ lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread();
+ if (thread_sp) {
+ lldb::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+ if (reg_ctx_sp) {
+ const RegisterInfo *reg_info =
+ reg_ctx_sp->GetRegisterInfoByName(reg_name, 0);
+ if (reg_info) {
+ lldb::addr_t mask_reg_val = reg_ctx_sp->ReadRegisterAsUnsigned(
+ reg_info->kinds[eRegisterKindLLDB], LLDB_INVALID_ADDRESS);
+ if (mask_reg_val != LLDB_INVALID_ADDRESS)
+ address_mask |= mask_reg_val;
+ }
+ }
+ }
+ return address_mask;
+}
+
+lldb::addr_t ABISysV_arm64::FixCodeAddress(lldb::addr_t pc) {
+ if (lldb::ProcessSP process_sp = GetProcessSP()) {
+ if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
+ !process_sp->GetCodeAddressMask())
+ process_sp->SetCodeAddressMask(
+ ReadLinuxProcessAddressMask(process_sp, "code_mask"));
+
+ return FixAddress(pc, process_sp->GetCodeAddressMask());
+ }
+ return pc;
+}
+
+lldb::addr_t ABISysV_arm64::FixDataAddress(lldb::addr_t pc) {
+ if (lldb::ProcessSP process_sp = GetProcessSP()) {
+ if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
+ !process_sp->GetDataAddressMask())
+ process_sp->SetDataAddressMask(
+ ReadLinuxProcessAddressMask(process_sp, "data_mask"));
+
+ return FixAddress(pc, process_sp->GetDataAddressMask());
+ }
+ return pc;
+}
+
void ABISysV_arm64::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
"SysV ABI for AArch64 targets", CreateInstance);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
index aeb74acc38b5..3428a7ad9418 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
@@ -67,6 +67,8 @@ public:
bool GetPointerReturnRegister(const char *&name) override;
+ lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
+
// Static Functions
static void Initialize();
@@ -83,6 +85,9 @@ public:
uint32_t GetPluginVersion() override;
+ lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
+ lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
+
protected:
lldb::ValueObjectSP
GetReturnValueObjectImpl(lldb_private::Thread &thread,
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
index be8586722d8f..60cdbc534113 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
@@ -466,7 +466,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread,
if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
return ValueObjectSP();
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
}
// Pointer return type.
else if (type_flags & eTypeIsPointer) {
@@ -474,7 +474,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread,
LLDB_REGNUM_GENERIC_ARG1);
value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
}
// Floating point return type.
else if (type_flags & eTypeIsFloat) {
@@ -537,7 +537,7 @@ ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread,
auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1);
value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
}
// Floating point return type.
else if (retType.isFloatingPointTy()) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
index 06c4590b7740..e429f3ee0cc4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
@@ -1824,6 +1824,7 @@ bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
index 26b3152bed16..3e544e0483a7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
@@ -1617,7 +1617,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
UINT32_MAX;
value.GetScalar() = ptr;
- } else if (compiler_type.IsVectorType(nullptr, nullptr)) {
+ } else if (compiler_type.IsVectorType()) {
if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
is_vfp_candidate = true;
vfp_byte_size = 8;
@@ -1704,7 +1704,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
if (homogeneous_count > 0 && homogeneous_count <= 4) {
llvm::Optional<uint64_t> base_byte_size =
base_type.GetByteSize(&thread);
- if (base_type.IsVectorType(nullptr, nullptr)) {
+ if (base_type.IsVectorType()) {
if (base_byte_size &&
(*base_byte_size == 8 || *base_byte_size == 16)) {
is_vfp_candidate = true;
@@ -1940,6 +1940,7 @@ bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
index 47aaefd3b228..6794f7d07210 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
@@ -1225,6 +1225,7 @@ bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
index d66e0926ad99..538ec06c3b0d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
@@ -985,6 +985,7 @@ bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
index 751555722dac..7220508c75ff 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
@@ -764,7 +764,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
bool success = false;
if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
@@ -1156,6 +1156,7 @@ bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
index 91d2e59ed632..98a14b50cbf3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
@@ -520,7 +520,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
const uint32_t type_flags = return_compiler_type.GetTypeInfo();
if (type_flags & eTypeIsScalar) {
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
bool success = false;
if (type_flags & eTypeIsInteger) {
@@ -603,7 +603,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
value.GetScalar() =
(uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
@@ -683,8 +683,6 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
r3_value.GetData(r3_data);
rdx_value.GetData(rdx_data);
- uint32_t fp_bytes =
- 0; // Tracks how much of the xmm registers we've consumed so far
uint32_t integer_bytes =
0; // Tracks how much of the r3/rds registers we've consumed so far
@@ -751,7 +749,6 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
break;
} else if (*field_bit_width == 64) {
copy_from_offset = 0;
- fp_bytes += field_byte_width;
} else if (*field_bit_width == 32) {
// This one is kind of complicated. If we are in an "eightbyte"
// with another float, we'll be stuffed into an xmm register with
@@ -815,8 +812,6 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
copy_from_offset = integer_bytes - 8;
integer_bytes += field_byte_width;
}
- } else {
- fp_bytes += field_byte_width;
}
}
}
@@ -900,6 +895,7 @@ bool ABISysV_ppc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
UnwindPlan::RowSP row(new UnwindPlan::Row);
const int32_t ptr_size = 4;
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
index c7cb7736df9f..7cc9482e7c5d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
@@ -577,7 +577,7 @@ private:
ValueSP NewScalarValue(CompilerType &type) {
ValueSP value_sp(new Value);
value_sp->SetCompilerType(type);
- value_sp->SetValueType(Value::eValueTypeScalar);
+ value_sp->SetValueType(Value::ValueType::Scalar);
return value_sp;
}
@@ -1003,6 +1003,7 @@ bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
UnwindPlan::RowSP row(new UnwindPlan::Row);
const int32_t ptr_size = 8;
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
index 22a64170017b..88e85111d871 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
@@ -487,7 +487,7 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
const uint32_t type_flags = return_compiler_type.GetTypeInfo();
if (type_flags & eTypeIsScalar) {
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
bool success = false;
if (type_flags & eTypeIsInteger) {
@@ -571,7 +571,7 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
value.GetScalar() =
(uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
index 89112deb2c4a..461e4af599d3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
@@ -389,6 +389,7 @@ bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
index 2f47d3f462d2..7d2f0a64d679 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
@@ -378,14 +378,14 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
uint32_t ptr =
thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
0xffffffff;
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
value.GetScalar() = ptr;
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if ((type_flags & eTypeIsScalar) ||
(type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
{
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
llvm::Optional<uint64_t> byte_size =
return_compiler_type.GetByteSize(&thread);
if (!byte_size)
@@ -453,7 +453,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
uint32_t enm =
thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
0xffffffff;
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
value.GetScalar() = enm;
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
@@ -652,6 +652,7 @@ bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
index 2aa2c02b2e87..196b45b3b6da 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
@@ -399,7 +399,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
const uint32_t type_flags = return_compiler_type.GetTypeInfo();
if (type_flags & eTypeIsScalar) {
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
bool success = false;
if (type_flags & eTypeIsInteger) {
@@ -487,7 +487,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
value.GetScalar() =
(uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
0);
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
@@ -887,6 +887,7 @@ bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
const int32_t ptr_size = 8;
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
index 06e0ce40836d..6c473c652c5f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
@@ -408,7 +408,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
const uint32_t type_flags = return_compiler_type.GetTypeInfo();
if (type_flags & eTypeIsScalar) {
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
bool success = false;
if (type_flags & eTypeIsInteger) {
@@ -494,7 +494,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
value.GetScalar() =
(uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
0);
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
@@ -767,6 +767,7 @@ bool ABIWindows_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
const int32_t ptr_size = 8;
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
row->SetOffset(0);
+ row->SetUnspecifiedRegistersAreUndefined(true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
new file mode 100644
index 000000000000..9994cc293d6a
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
@@ -0,0 +1,45 @@
+//===-- ArchitectureAArch64.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Architecture/AArch64/ArchitectureAArch64.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/ArchSpec.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+LLDB_PLUGIN_DEFINE(ArchitectureAArch64)
+
+ConstString ArchitectureAArch64::GetPluginNameStatic() {
+ return ConstString("aarch64");
+}
+
+void ArchitectureAArch64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "AArch64-specific algorithms",
+ &ArchitectureAArch64::Create);
+}
+
+void ArchitectureAArch64::Terminate() {
+ PluginManager::UnregisterPlugin(&ArchitectureAArch64::Create);
+}
+
+std::unique_ptr<Architecture>
+ArchitectureAArch64::Create(const ArchSpec &arch) {
+ auto machine = arch.GetMachine();
+ if (machine != llvm::Triple::aarch64 && machine != llvm::Triple::aarch64_be &&
+ machine != llvm::Triple::aarch64_32) {
+ return nullptr;
+ }
+ return std::unique_ptr<Architecture>(new ArchitectureAArch64());
+}
+
+ConstString ArchitectureAArch64::GetPluginName() {
+ return GetPluginNameStatic();
+}
+uint32_t ArchitectureAArch64::GetPluginVersion() { return 1; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h
new file mode 100644
index 000000000000..775478cc9338
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h
@@ -0,0 +1,40 @@
+//===-- ArchitectureAArch64.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H
+#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H
+
+#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
+#include "lldb/Core/Architecture.h"
+
+namespace lldb_private {
+
+class ArchitectureAArch64 : public Architecture {
+public:
+ static ConstString GetPluginNameStatic();
+ static void Initialize();
+ static void Terminate();
+
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ void OverrideStopInfo(Thread &thread) const override{};
+
+ const MemoryTagManager *GetMemoryTagManager() const override {
+ return &m_memory_tag_manager;
+ }
+
+private:
+ static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+ ArchitectureAArch64() = default;
+ MemoryTagManagerAArch64MTE m_memory_tag_manager;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
index 22508969ceed..757c91570009 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
@@ -160,7 +160,6 @@ Instruction *ArchitectureMips::GetInstructionAtAddress(
InstructionList instruction_list;
InstructionSP prev_insn;
- bool prefer_file_cache = true; // Read from file
uint32_t inst_to_choose = 0;
Address addr = resolved_addr;
@@ -171,8 +170,7 @@ Instruction *ArchitectureMips::GetInstructionAtAddress(
uint32_t insn_size = 0;
disasm_sp->ParseInstructions(target, addr,
- {Disassembler::Limit::Bytes, i * 2}, nullptr,
- prefer_file_cache);
+ {Disassembler::Limit::Bytes, i * 2}, nullptr);
uint32_t num_insns = disasm_sp->GetInstructionList().GetSize();
if (num_insns) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
index 8a2d3232a39a..7cd505d0ed29 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -905,7 +905,8 @@ DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple, const char *cpu,
return Instance();
std::unique_ptr<llvm::MCContext> context_up(
- new llvm::MCContext(asm_info_up.get(), reg_info_up.get(), nullptr));
+ new llvm::MCContext(llvm::Triple(triple), asm_info_up.get(),
+ reg_info_up.get(), subtarget_info_up.get()));
if (!context_up)
return Instance();
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
index 5707f8858f6c..c34e02ed5678 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
@@ -35,15 +35,13 @@ class HexagonDYLDRendezvous {
// the layout of this struct is not binary compatible, it is simply large
// enough to hold the information on both 32 and 64 bit platforms.
struct Rendezvous {
- uint64_t version;
- lldb::addr_t map_addr;
- lldb::addr_t brk;
- uint64_t state;
- lldb::addr_t ldbase;
-
- Rendezvous()
- : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
- state(0), ldbase(0) {}
+ uint64_t version = 0;
+ lldb::addr_t map_addr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t brk = LLDB_INVALID_ADDRESS;
+ uint64_t state = 0;
+ lldb::addr_t ldbase = 0;
+
+ Rendezvous() = default;
};
public:
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 3e88d88f407a..5775f5a730cd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -38,13 +38,13 @@ class DYLDRendezvous {
// the layout of this struct is not binary compatible, it is simply large
// enough to hold the information on both 32 and 64 bit platforms.
struct Rendezvous {
- uint64_t version;
- lldb::addr_t map_addr;
- lldb::addr_t brk;
- uint64_t state;
- lldb::addr_t ldbase;
+ uint64_t version = 0;
+ lldb::addr_t map_addr = 0;
+ lldb::addr_t brk = 0;
+ uint64_t state = 0;
+ lldb::addr_t ldbase = 0;
- Rendezvous() : version(0), map_addr(0), brk(0), state(0), ldbase(0) {}
+ Rendezvous() = default;
};
public:
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index c1fceeb1482c..8a5528f1e474 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -10,6 +10,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "DynamicLoaderStatic.h"
@@ -105,6 +106,15 @@ void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
// the file...
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp) {
+ // If this section already has a load address set in the target,
+ // don't re-set it to the file address. Something may have
+ // set it to a more correct value already.
+ if (m_process->GetTarget()
+ .GetSectionLoadList()
+ .GetSectionLoadAddress(section_sp) !=
+ LLDB_INVALID_ADDRESS) {
+ continue;
+ }
if (m_process->GetTarget().SetSectionLoadAddress(
section_sp, section_sp->GetFileAddress()))
changed = true;
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 7f9504b9b3a9..54dfa3e9d6f2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -28,7 +28,7 @@ LLDB_PLUGIN_DEFINE(DynamicLoaderWindowsDYLD)
DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process)
: DynamicLoader(process) {}
-DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {}
+DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() = default;
void DynamicLoaderWindowsDYLD::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
@@ -193,7 +193,7 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
AddressRange range(pc, 2 * 15);
DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
- arch, nullptr, nullptr, m_process->GetTarget(), range, true);
+ arch, nullptr, nullptr, m_process->GetTarget(), range);
if (!disassembler_sp) {
return ThreadPlanSP();
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 3edbc4ab98c0..85e2fcfc838c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -15,7 +15,6 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
-#include "stdlib.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
@@ -27,6 +26,7 @@
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
using namespace llvm;
using namespace clang;
@@ -43,7 +43,7 @@ ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
-ASTResultSynthesizer::~ASTResultSynthesizer() {}
+ASTResultSynthesizer::~ASTResultSynthesizer() = default;
void ASTResultSynthesizer::Initialize(ASTContext &Context) {
m_ast_context = &Context;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
index 40f0de40da52..a2722db5d24a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
@@ -9,7 +9,6 @@
#include "ASTStructExtractor.h"
#include "lldb/Utility/Log.h"
-#include "stdlib.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
@@ -21,6 +20,7 @@
#include "clang/Sema/Sema.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
using namespace llvm;
using namespace clang;
@@ -38,7 +38,7 @@ ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,
m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
-ASTStructExtractor::~ASTStructExtractor() {}
+ASTStructExtractor::~ASTStructExtractor() = default;
void ASTStructExtractor::Initialize(ASTContext &Context) {
m_ast_context = &Context;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
index 1e438ed9d73e..a95fce1c5aa9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
@@ -8,17 +8,17 @@
#include "ASTUtils.h"
-lldb_private::ExternalASTSourceWrapper::~ExternalASTSourceWrapper() {}
+lldb_private::ExternalASTSourceWrapper::~ExternalASTSourceWrapper() = default;
void lldb_private::ExternalASTSourceWrapper::PrintStats() {
m_Source->PrintStats();
}
-lldb_private::ASTConsumerForwarder::~ASTConsumerForwarder() {}
+lldb_private::ASTConsumerForwarder::~ASTConsumerForwarder() = default;
void lldb_private::ASTConsumerForwarder::PrintStats() { m_c->PrintStats(); }
-lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() {}
+lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() = default;
void lldb_private::SemaSourceWithPriorities::PrintStats() {
for (size_t i = 0; i < Sources.size(); ++i)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index e2601a059bb7..94647b0ef978 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -184,7 +184,7 @@ private:
}
public:
- DeclContextOverride() {}
+ DeclContextOverride() = default;
void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) {
for (DeclContext *decl_context = decl->getLexicalDeclContext();
@@ -359,9 +359,6 @@ bool ClangASTImporter::CanImport(const CompilerType &type) {
if (!ClangUtil::IsClangType(type))
return false;
- // TODO: remove external completion BOOL
- // CompleteAndFetchChildren should get the Decl out and check for the
-
clang::QualType qual_type(
ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
@@ -435,8 +432,6 @@ bool ClangASTImporter::CanImport(const CompilerType &type) {
bool ClangASTImporter::Import(const CompilerType &type) {
if (!ClangUtil::IsClangType(type))
return false;
- // TODO: remove external completion BOOL
- // CompleteAndFetchChildren should get the Decl out and check for the
clang::QualType qual_type(
ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
@@ -830,6 +825,10 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
// Check which ASTContext this declaration originally came from.
DeclOrigin origin = m_master.GetDeclOrigin(From);
+
+ // Prevent infinite recursion when the origin tracking contains a cycle.
+ assert(origin.decl != From && "Origin points to itself?");
+
// If it originally came from the target ASTContext then we can just
// pretend that the original is the one we imported. This can happen for
// example when inspecting a persistent declaration from the scratch
@@ -889,6 +888,37 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
LLDB_LOG(log, "[ClangASTImporter] Complete definition not found");
}
+ // Disable the minimal import for fields that have record types. There is
+ // no point in minimally importing the record behind their type as Clang
+ // will anyway request their definition when the FieldDecl is added to the
+ // RecordDecl (as Clang will query the FieldDecl's type for things such
+ // as a deleted constexpr destructor).
+ // By importing the type ahead of time we avoid some corner cases where
+ // the FieldDecl's record is importing in the middle of Clang's
+ // `DeclContext::addDecl` logic.
+ if (clang::FieldDecl *fd = dyn_cast<FieldDecl>(From)) {
+ // This is only necessary because we do the 'minimal import'. Remove this
+ // once LLDB stopped using that mode.
+ assert(isMinimalImport() && "Only necessary for minimal import");
+ QualType field_type = fd->getType();
+ if (field_type->isRecordType()) {
+ // First get the underlying record and minimally import it.
+ clang::TagDecl *record_decl = field_type->getAsTagDecl();
+ llvm::Expected<Decl *> imported = Import(record_decl);
+ if (!imported)
+ return imported.takeError();
+ // Check how/if the import got redirected to a different AST. Now
+ // import the definition of what was actually imported. If there is no
+ // origin then that means the record was imported by just picking a
+ // compatible type in the target AST (in which case there is no more
+ // importing to do).
+ if (clang::Decl *origin = m_master.GetDeclOrigin(*imported).decl) {
+ if (llvm::Error def_err = ImportDefinition(record_decl))
+ return std::move(def_err);
+ }
+ }
+ }
+
return ASTImporter::ImportImpl(From);
}
@@ -904,16 +934,6 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
MapImported(from, to);
ASTImporter::Imported(from, to);
- /*
- if (to_objc_interface)
- to_objc_interface->startDefinition();
-
- CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
-
- if (to_cxx_record)
- to_cxx_record->startDefinition();
- */
-
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
if (llvm::Error err = ImportDefinition(from)) {
@@ -1088,22 +1108,23 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
DeclOrigin origin = from_context_md->getOrigin(from);
if (origin.Valid()) {
- if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID)
- if (origin.ctx != &to->getASTContext())
+ if (origin.ctx != &to->getASTContext()) {
+ if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID)
to_context_md->setOrigin(to, origin);
- ImporterDelegateSP direct_completer =
- m_master.GetDelegate(&to->getASTContext(), origin.ctx);
+ ImporterDelegateSP direct_completer =
+ m_master.GetDelegate(&to->getASTContext(), origin.ctx);
- if (direct_completer.get() != this)
- direct_completer->ASTImporter::Imported(origin.decl, to);
+ if (direct_completer.get() != this)
+ direct_completer->ASTImporter::Imported(origin.decl, to);
- LLDB_LOG(log,
- " [ClangASTImporter] Propagated origin "
- "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to "
- "(ASTContext*){3}",
- origin.decl, origin.ctx, &from->getASTContext(),
- &to->getASTContext());
+ LLDB_LOG(log,
+ " [ClangASTImporter] Propagated origin "
+ "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to "
+ "(ASTContext*){3}",
+ origin.decl, origin.ctx, &from->getASTContext(),
+ &to->getASTContext());
+ }
} else {
if (m_new_decl_listener)
m_new_decl_listener->NewDeclImported(from, to);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
index bf4ad174cf9c..4f589d34aa48 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
@@ -23,6 +23,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/lldb-types.h"
#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h"
@@ -34,6 +35,32 @@ namespace lldb_private {
class ClangASTMetadata;
class TypeSystemClang;
+/// Manages and observes all Clang AST node importing in LLDB.
+///
+/// The ClangASTImporter takes care of two things:
+///
+/// 1. Keeps track of all ASTImporter instances in LLDB.
+///
+/// Clang's ASTImporter takes care of importing types from one ASTContext to
+/// another. This class expands this concept by allowing copying from several
+/// ASTContext instances to several other ASTContext instances. Instead of
+/// constructing a new ASTImporter manually to copy over a type/decl, this class
+/// can be asked to do this. It will construct a ASTImporter for the caller (and
+/// will cache the ASTImporter instance for later use) and then perform the
+/// import.
+///
+/// This mainly prevents that a caller might construct several ASTImporter
+/// instances for the same source/target ASTContext combination. As the
+/// ASTImporter has an internal state that keeps track of already imported
+/// declarations and so on, using only one ASTImporter instance is more
+/// efficient and less error-prone than using multiple.
+///
+/// 2. Keeps track of from where declarations were imported (origin-tracking).
+/// The ASTImporter instances in this class usually only performa a minimal
+/// import, i.e., only a shallow copy is made that is filled out on demand
+/// when more information is requested later on. This requires record-keeping
+/// of where any shallow clone originally came from so that the right original
+/// declaration can be found and used as the source of any missing information.
class ClangASTImporter {
public:
struct LayoutInfo {
@@ -52,12 +79,34 @@ public:
: m_file_manager(clang::FileSystemOptions(),
FileSystem::Instance().GetVirtualFileSystem()) {}
+ /// Copies the given type and the respective declarations to the destination
+ /// type system.
+ ///
+ /// This function does a shallow copy and requires that the target AST
+ /// has an ExternalASTSource which queries this ClangASTImporter instance
+ /// for any additional information that is maybe lacking in the shallow copy.
+ /// This also means that the type system of src_type can *not* be deleted
+ /// after this function has been called. If you need to delete the source
+ /// type system you either need to delete the destination type system first
+ /// or use \ref ClangASTImporter::DeportType.
+ ///
+ /// \see ClangASTImporter::DeportType
CompilerType CopyType(TypeSystemClang &dst, const CompilerType &src_type);
+ /// \see ClangASTImporter::CopyType
clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
+ /// Copies the given type and the respective declarations to the destination
+ /// type system.
+ ///
+ /// Unlike CopyType this function ensures that types/declarations which are
+ /// originally from the AST of src_type are fully copied over. The type
+ /// system of src_type can safely be deleted after calling this function.
+ /// \see ClangASTImporter::CopyType
CompilerType DeportType(TypeSystemClang &dst, const CompilerType &src_type);
+ /// Copies the given decl to the destination type system.
+ /// \see ClangASTImporter::DeportType
clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
/// Sets the layout for the given RecordDecl. The layout will later be
@@ -78,8 +127,22 @@ public:
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
&vbase_offsets);
+ /// Returns true iff the given type was copied from another TypeSystemClang
+ /// and the original type in this other TypeSystemClang might contain
+ /// additional information (e.g., the definition of a 'class' type) that could
+ /// be imported.
+ ///
+ /// \see ClangASTImporter::Import
bool CanImport(const CompilerType &type);
+ /// If the given type was copied from another TypeSystemClang then copy over
+ /// all missing information (e.g., the definition of a 'class' type).
+ ///
+ /// \return True iff an original type in another TypeSystemClang was found.
+ /// Note: Does *not* return false if an original type was found but
+ /// no information was imported over.
+ ///
+ /// \see ClangASTImporter::Import
bool Import(const CompilerType &type);
bool CompleteType(const CompilerType &compiler_type);
@@ -94,6 +157,14 @@ public:
bool RequireCompleteType(clang::QualType type);
+ /// Updates the internal origin-tracking information so that the given
+ /// 'original' decl is from now on used to import additional information
+ /// into the given decl.
+ ///
+ /// Usually the origin-tracking in the ClangASTImporter is automatically
+ /// updated when a declaration is imported, so the only valid reason to ever
+ /// call this is if there is a 'better' original decl and the target decl
+ /// is only a shallow clone that lacks any contents.
void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl);
ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl);
@@ -145,10 +216,13 @@ public:
void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
struct DeclOrigin {
- DeclOrigin() : ctx(nullptr), decl(nullptr) {}
+ DeclOrigin() = default;
DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl)
- : ctx(_ctx), decl(_decl) {}
+ : ctx(_ctx), decl(_decl) {
+ // The decl has to be in its associated ASTContext.
+ assert(_decl == nullptr || &_decl->getASTContext() == _ctx);
+ }
DeclOrigin(const DeclOrigin &rhs) {
ctx = rhs.ctx;
@@ -162,8 +236,8 @@ public:
bool Valid() const { return (ctx != nullptr || decl != nullptr); }
- clang::ASTContext *ctx;
- clang::Decl *decl;
+ clang::ASTContext *ctx = nullptr;
+ clang::Decl *decl = nullptr;
};
/// Listener interface used by the ASTImporterDelegate to inform other code
@@ -190,6 +264,16 @@ public:
: clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx,
master.m_file_manager, true /*minimal*/),
m_master(master), m_source_ctx(source_ctx) {
+ // Target and source ASTContext shouldn't be identical. Importing AST
+ // nodes within the same AST doesn't make any sense as the whole idea
+ // is to import them to a different AST.
+ lldbassert(target_ctx != source_ctx && "Can't import into itself");
+ // This is always doing a minimal import of any declarations. This means
+ // that there has to be an ExternalASTSource in the target ASTContext
+ // (that should implement the callbacks that complete any declarations
+ // on demand). Without an ExternalASTSource, this ASTImporter will just
+ // do a minimal import and the imported declarations won't be completed.
+ assert(target_ctx->getExternalSource() && "Missing ExternalSource");
setODRHandling(clang::ASTImporter::ODRHandlingType::Liberal);
}
@@ -272,6 +356,13 @@ public:
/// Sets the DeclOrigin for the given Decl and overwrites any existing
/// DeclOrigin.
void setOrigin(const clang::Decl *decl, DeclOrigin origin) {
+ // Setting the origin of any decl to itself (or to a different decl
+ // in the same ASTContext) doesn't make any sense. It will also cause
+ // ASTImporterDelegate::ImportImpl to infinite recurse when trying to find
+ // the 'original' Decl when importing code.
+ assert(&decl->getASTContext() != origin.ctx &&
+ "Trying to set decl origin to its own ASTContext?");
+ assert(decl != origin.decl && "Trying to set decl origin to itself?");
m_origins[decl] = origin;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 0f34c48c7e82..b43423707ae1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -479,10 +479,7 @@ void ClangASTSource::FindExternalLexicalDecls(
decl->getDeclKindName(), ast_dump);
}
- Decl *copied_decl = CopyDecl(decl);
-
- if (!copied_decl)
- continue;
+ CopyDecl(decl);
// FIXME: We should add the copied decl to the 'decls' list. This would
// add the copied Decl into the DeclContext and make sure that we
@@ -492,12 +489,6 @@ void ClangASTSource::FindExternalLexicalDecls(
// lookup issues later on.
// We can't just add them for now as the ASTImporter already added the
// decl into the DeclContext and this would add it twice.
-
- if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) {
- QualType copied_field_type = copied_field->getType();
-
- m_ast_importer_sp->RequireCompleteType(copied_field_type);
- }
} else {
SkippedDecls = true;
}
@@ -850,8 +841,8 @@ void ClangASTSource::FindDeclInModules(NameSearchContext &context,
ConstString name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- ClangModulesDeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor();
+ std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+ GetClangModulesDeclVendor();
if (!modules_decl_vendor)
return;
@@ -1143,8 +1134,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
// Check the modules only if the debug information didn't have a complete
// interface.
- if (ClangModulesDeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor()) {
+ if (std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+ GetClangModulesDeclVendor()) {
ConstString interface_name(interface_decl->getNameAsString().c_str());
bool append = false;
uint32_t max_matches = 1;
@@ -1313,8 +1304,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
// Check the modules only if the debug information didn't have a complete
// interface.
- ClangModulesDeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor();
+ std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+ GetClangModulesDeclVendor();
if (!modules_decl_vendor)
break;
@@ -1570,10 +1561,10 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
if (log) {
LLDB_LOG(log, "LRT returned:");
- LLDB_LOG(log, "LRT Original = (RecordDecl*)%p",
+ LLDB_LOG(log, "LRT Original = (RecordDecl*){0}",
static_cast<const void *>(origin_record.decl));
- LLDB_LOG(log, "LRT Size = %" PRId64, size);
- LLDB_LOG(log, "LRT Alignment = %" PRId64, alignment);
+ LLDB_LOG(log, "LRT Size = {0}", size);
+ LLDB_LOG(log, "LRT Alignment = {0}", alignment);
LLDB_LOG(log, "LRT Fields:");
for (RecordDecl::field_iterator fi = record->field_begin(),
fe = record->field_end();
@@ -1750,3 +1741,10 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
return m_clang_ast_context->GetType(copied_qual_type);
}
+
+std::shared_ptr<ClangModulesDeclVendor>
+ClangASTSource::GetClangModulesDeclVendor() {
+ auto persistent_vars = llvm::cast<ClangPersistentVariables>(
+ m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
+ return persistent_vars->GetClangModulesDeclVendor();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 14761fbeb26b..3afd1fd5f2d1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -314,6 +314,8 @@ protected:
/// The imported type.
CompilerType GuardedCopyType(const CompilerType &src_type);
+ std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();
+
public:
/// Returns true if a name should be ignored by name lookup.
///
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
index bf52bec4b1fa..6313117c08d6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
@@ -22,7 +22,7 @@ class ClangDeclVendor : public DeclVendor {
public:
ClangDeclVendor(DeclVendorKind kind) : DeclVendor(kind) {}
- virtual ~ClangDeclVendor() {}
+ virtual ~ClangDeclVendor() = default;
using DeclVendor::FindDecls;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 852ce3bbd3db..731b81c61a6f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -350,7 +350,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!var)
return false;
- LLDB_LOG(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+ LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure",
decl, name, var->GetName());
// We know entity->m_parser_vars is valid because we used a parser variable
@@ -752,7 +752,7 @@ void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
MaybeRegisterFunctionBody(parser_function_decl);
}
- LLDB_LOG(log, " CEDM::FEVD Found persistent decl %s", name);
+ LLDB_LOG(log, " CEDM::FEVD Found persistent decl {0}", name);
context.AddNamedDecl(parser_named_decl);
}
@@ -1021,7 +1021,8 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor(
if (!m_target)
return;
- auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor();
+ std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+ GetClangModulesDeclVendor();
if (!modules_decl_vendor)
return;
@@ -1213,8 +1214,8 @@ void ClangExpressionDeclMap::LookupFunction(
std::vector<clang::NamedDecl *> decls_from_modules;
if (target) {
- if (ClangModulesDeclVendor *decl_vendor =
- target->GetClangModulesDeclVendor()) {
+ if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+ GetClangModulesDeclVendor()) {
decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
}
}
@@ -1493,7 +1494,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
if (var_location_expr.GetExpressionData(const_value_extractor)) {
var_location = Value(const_value_extractor.GetDataStart(),
const_value_extractor.GetByteSize());
- var_location.SetValueType(Value::eValueTypeHostAddress);
+ var_location.SetValueType(Value::ValueType::HostAddress);
} else {
LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());
return false;
@@ -1512,10 +1513,10 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
if (parser_type)
*parser_type = TypeFromParser(type_to_use);
- if (var_location.GetContextType() == Value::eContextTypeInvalid)
+ if (var_location.GetContextType() == Value::ContextType::Invalid)
var_location.SetCompilerType(type_to_use);
- if (var_location.GetValueType() == Value::eValueTypeFileAddress) {
+ if (var_location.GetValueType() == Value::ValueType::FileAddress) {
SymbolContext var_sc;
var->CalculateSymbolContext(&var_sc);
@@ -1529,7 +1530,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
if (load_addr != LLDB_INVALID_ADDRESS) {
var_location.GetScalar() = load_addr;
- var_location.SetValueType(Value::eValueTypeLoadAddress);
+ var_location.SetValueType(Value::ValueType::LoadAddress);
}
}
@@ -1665,11 +1666,11 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
const Address symbol_address = symbol.GetAddress();
lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
- // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
+ // parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType,
// user_type.GetOpaqueQualType());
parser_vars->m_lldb_value.SetCompilerType(user_type);
parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+ parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
@@ -1860,14 +1861,14 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
entity->GetParserVars(GetParserID());
if (load_addr != LLDB_INVALID_ADDRESS) {
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+ parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
parser_vars->m_lldb_value.GetScalar() = load_addr;
} else {
// We have to try finding a file address.
lldb::addr_t file_addr = fun_address.GetFileAddress();
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
+ parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress);
parser_vars->m_lldb_value.GetScalar() = file_addr;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index a9cd5d166b9d..e39dc587bc43 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -9,8 +9,8 @@
#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
-#include <signal.h>
-#include <stdint.h>
+#include <csignal>
+#include <cstdint>
#include <vector>
@@ -248,10 +248,10 @@ public:
lldb::SymbolType symbol_type);
struct TargetInfo {
- lldb::ByteOrder byte_order;
- size_t address_byte_size;
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+ size_t address_byte_size = 0;
- TargetInfo() : byte_order(lldb::eByteOrderInvalid), address_byte_size(0) {}
+ TargetInfo() = default;
bool IsValid() {
return (byte_order != lldb::eByteOrderInvalid && address_byte_size != 0);
@@ -308,7 +308,7 @@ private:
/// The following values should not live beyond parsing
class ParserVars {
public:
- ParserVars() {}
+ ParserVars() = default;
Target *GetTarget() {
if (m_exe_ctx.GetTargetPtr())
@@ -353,16 +353,15 @@ private:
/// The following values contain layout information for the materialized
/// struct, but are not specific to a single materialization
struct StructVars {
- StructVars()
- : m_struct_alignment(0), m_struct_size(0), m_struct_laid_out(false),
- m_result_name(), m_object_pointer_type(nullptr, nullptr) {}
-
- lldb::offset_t
- m_struct_alignment; ///< The alignment of the struct in bytes.
- size_t m_struct_size; ///< The size of the struct in bytes.
- bool m_struct_laid_out; ///< True if the struct has been laid out and the
- ///layout is valid (that is, no new fields have been
- ///added since).
+ StructVars() : m_result_name(), m_object_pointer_type(nullptr, nullptr) {}
+
+ lldb::offset_t m_struct_alignment =
+ 0; ///< The alignment of the struct in bytes.
+ size_t m_struct_size = 0; ///< The size of the struct in bytes.
+ bool m_struct_laid_out =
+ false; ///< True if the struct has been laid out and the
+ /// layout is valid (that is, no new fields have been
+ /// added since).
ConstString
m_result_name; ///< The name of the result variable ($1, for example)
TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index e33e5df22236..37bcaf000cfc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -38,7 +38,7 @@ public:
ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper) {}
/// Destructor
- virtual ~ClangExpressionHelper() {}
+ virtual ~ClangExpressionHelper() = default;
/// Return the object that the parser should use when resolving external
/// values. May be NULL if everything should be self-contained.
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 7644a5e1423e..0b5e1ab059d2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -343,6 +343,7 @@ static void SetupDefaultClangDiagnostics(CompilerInstance &compiler) {
const std::vector<const char *> groupsToIgnore = {
"unused-value",
"odr",
+ "unused-getter-return-value",
};
for (const char *group : groupsToIgnore) {
compiler.getDiagnostics().setSeverityForGroup(
@@ -513,7 +514,7 @@ ClangExpressionParser::ClangExpressionParser(
LLDB_LOGF(log, "Using SIMD alignment: %d",
target_info->getSimdDefaultAlign());
LLDB_LOGF(log, "Target datalayout string: '%s'",
- target_info->getDataLayout().getStringRepresentation().c_str());
+ target_info->getDataLayoutString());
LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str());
LLDB_LOGF(log, "Target vector alignment: %d",
target_info->getMaxVectorAlign());
@@ -657,7 +658,8 @@ ClangExpressionParser::ClangExpressionParser(
//
// FIXME: We shouldn't need to do this, the target should be immutable once
// created. This complexity should be lifted elsewhere.
- m_compiler->getTarget().adjust(m_compiler->getLangOpts());
+ m_compiler->getTarget().adjust(m_compiler->getDiagnostics(),
+ m_compiler->getLangOpts());
// 6. Set up the diagnostic buffer for reporting errors
@@ -686,11 +688,11 @@ ClangExpressionParser::ClangExpressionParser(
break;
}
- if (ClangModulesDeclVendor *decl_vendor =
- target_sp->GetClangModulesDeclVendor()) {
- if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
- target_sp->GetPersistentExpressionStateForLanguage(
- lldb::eLanguageTypeC))) {
+ if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
+ target_sp->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC))) {
+ if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+ clang_persistent_vars->GetClangModulesDeclVendor()) {
std::unique_ptr<PPCallbacks> pp_callbacks(
new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars,
m_compiler->getSourceManager()));
@@ -723,7 +725,7 @@ ClangExpressionParser::ClangExpressionParser(
m_compiler->getCodeGenOpts(), *m_llvm_context));
}
-ClangExpressionParser::~ClangExpressionParser() {}
+ClangExpressionParser::~ClangExpressionParser() = default;
namespace {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index 180e08b03c93..31707f81a270 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -31,6 +31,7 @@
using namespace lldb_private;
#define PREFIX_NAME "<lldb wrapper prefix>"
+#define SUFFIX_NAME "<lldb wrapper suffix>"
const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME;
@@ -73,6 +74,9 @@ extern "C"
}
)";
+const char *ClangExpressionSourceCode::g_expression_suffix =
+ "\n;\n#line 1 \"" SUFFIX_NAME "\"\n";
+
namespace {
class AddMacroState {
@@ -180,7 +184,7 @@ lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode(
// containing only the user expression. This will hide our wrapper code
// from the user when we render diagnostics with Clang.
m_start_marker = "#line 1 \"" + filename.str() + "\"\n";
- m_end_marker = "\n;\n#line 1 \"<lldb wrapper suffix>\"\n";
+ m_end_marker = g_expression_suffix;
}
namespace {
@@ -314,10 +318,11 @@ bool ClangExpressionSourceCode::GetText(
}
}
- ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor();
auto *persistent_vars = llvm::cast<ClangPersistentVariables>(
target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
- if (decl_vendor && persistent_vars) {
+ std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+ persistent_vars->GetClangModulesDeclVendor();
+ if (decl_vendor) {
const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
persistent_vars->GetHandLoadedClangModules();
ClangModulesDeclVendor::ModuleVector modules_for_macros;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
index 9a54f0e3ad8d..54ae837fb30f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
@@ -27,6 +27,7 @@ public:
/// the user expression.
static const llvm::StringRef g_prefix_file_name;
static const char *g_expression_prefix;
+ static const char *g_expression_suffix;
/// The possible ways an expression can be wrapped.
enum class WrapKind {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index 58d589962abe..7bb68e78373f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -9,9 +9,9 @@
#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
+#include <csignal>
+#include <cstdint>
+#include <cstring>
#include <map>
#include <string>
@@ -116,19 +116,19 @@ public:
/// The following values should not live beyond parsing
class ParserVars {
public:
- ParserVars()
- : m_named_decl(nullptr), m_llvm_value(nullptr),
- m_lldb_value(), m_lldb_var(), m_lldb_sym(nullptr) {}
-
- const clang::NamedDecl
- *m_named_decl; ///< The Decl corresponding to this variable
- llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable;
- ///usually a GlobalValue
+ ParserVars() : m_lldb_value(), m_lldb_var() {}
+
+ const clang::NamedDecl *m_named_decl =
+ nullptr; ///< The Decl corresponding to this variable
+ llvm::Value *m_llvm_value =
+ nullptr; ///< The IR value corresponding to this variable;
+ /// usually a GlobalValue
lldb_private::Value
m_lldb_value; ///< The value found in LLDB for this variable
lldb::VariableSP m_lldb_var; ///< The original variable for this variable
- const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this
- ///variable, if it was a symbol
+ const lldb_private::Symbol *m_lldb_sym =
+ nullptr; ///< The original symbol for this
+ /// variable, if it was a symbol
};
private:
@@ -157,13 +157,13 @@ public:
/// The following values are valid if the variable is used by JIT code
struct JITVars {
- JITVars() : m_alignment(0), m_size(0), m_offset(0) {}
+ JITVars() = default;
- lldb::offset_t
- m_alignment; ///< The required alignment of the variable, in bytes
- size_t m_size; ///< The space required for the variable, in bytes
- lldb::offset_t
- m_offset; ///< The offset of the variable in the struct, in bytes
+ lldb::offset_t m_alignment =
+ 0; ///< The required alignment of the variable, in bytes
+ size_t m_size = 0; ///< The space required for the variable, in bytes
+ lldb::offset_t m_offset =
+ 0; ///< The offset of the variable in the struct, in bytes
};
private:
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 0c9ad2021035..2cfa9a4c9ccf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -59,7 +59,7 @@ ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope,
}
// Destructor
-ClangFunctionCaller::~ClangFunctionCaller() {}
+ClangFunctionCaller::~ClangFunctionCaller() = default;
unsigned
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index c014ad504d37..336058a5abb9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -42,9 +42,9 @@
using namespace lldb_private;
namespace {
-// Any Clang compiler requires a consumer for diagnostics. This one stores
-// them as strings so we can provide them to the user in case a module failed
-// to load.
+/// Any Clang compiler requires a consumer for diagnostics. This one stores
+/// them as strings so we can provide them to the user in case a module failed
+/// to load.
class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
public:
StoringDiagnosticConsumer();
@@ -74,8 +74,8 @@ private:
Log *m_log;
};
-// The private implementation of our ClangModulesDeclVendor. Contains all the
-// Clang state required to load modules.
+/// The private implementation of our ClangModulesDeclVendor. Contains all the
+/// Clang state required to load modules.
class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
public:
ClangModulesDeclVendorImpl(
@@ -100,9 +100,9 @@ public:
std::function<bool(llvm::StringRef, llvm::StringRef)> handler) override;
private:
- void
- ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
- clang::Module *module);
+ typedef llvm::DenseSet<ModuleID> ExportedModuleSet;
+ void ReportModuleExportsHelper(ExportedModuleSet &exports,
+ clang::Module *module);
void ReportModuleExports(ModuleVector &exports, clang::Module *module);
@@ -120,7 +120,7 @@ private:
typedef std::vector<ConstString> ImportedModule;
typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
- typedef std::set<ModuleID> ImportedModuleSet;
+ typedef llvm::DenseSet<ModuleID> ImportedModuleSet;
ImportedModuleMap m_imported_modules;
ImportedModuleSet m_user_imported_modules;
// We assume that every ASTContext has an TypeSystemClang, so we also store
@@ -176,7 +176,7 @@ void StoringDiagnosticConsumer::EndSourceFile() {
ClangModulesDeclVendor::ClangModulesDeclVendor()
: ClangDeclVendor(eClangModuleDeclVendor) {}
-ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
+ClangModulesDeclVendor::~ClangModulesDeclVendor() = default;
ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
@@ -195,8 +195,7 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
}
void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
- std::set<ClangModulesDeclVendor::ModuleID> &exports,
- clang::Module *module) {
+ ExportedModuleSet &exports, clang::Module *module) {
if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
return;
@@ -206,20 +205,18 @@ void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
module->getExportedModules(sub_exports);
- for (clang::Module *module : sub_exports) {
+ for (clang::Module *module : sub_exports)
ReportModuleExportsHelper(exports, module);
- }
}
void ClangModulesDeclVendorImpl::ReportModuleExports(
ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {
- std::set<ClangModulesDeclVendor::ModuleID> exports_set;
+ ExportedModuleSet exports_set;
ReportModuleExportsHelper(exports_set, module);
- for (ModuleID module : exports_set) {
+ for (ModuleID module : exports_set)
exports.push_back(module);
- }
}
bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
@@ -237,17 +234,15 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
std::vector<ConstString> imported_module;
- for (ConstString path_component : module.path) {
+ for (ConstString path_component : module.path)
imported_module.push_back(path_component);
- }
{
ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
if (mi != m_imported_modules.end()) {
- if (exported_modules) {
+ if (exported_modules)
ReportModuleExports(*exported_modules, mi->second);
- }
return true;
}
}
@@ -338,9 +333,8 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
clang::Module *requested_module = DoGetModule(clang_path, true);
if (requested_module != nullptr) {
- if (exported_modules) {
+ if (exported_modules)
ReportModuleExports(*exported_modules, requested_module);
- }
m_imported_modules[imported_module] = requested_module;
@@ -388,9 +382,8 @@ uint32_t
ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
uint32_t max_matches,
std::vector<CompilerDecl> &decls) {
- if (!m_enabled) {
+ if (!m_enabled)
return 0;
- }
if (!append)
decls.clear();
@@ -423,18 +416,16 @@ ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
void ClangModulesDeclVendorImpl::ForEachMacro(
const ClangModulesDeclVendor::ModuleVector &modules,
std::function<bool(llvm::StringRef, llvm::StringRef)> handler) {
- if (!m_enabled) {
+ if (!m_enabled)
return;
- }
typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
ModulePriorityMap module_priorities;
ssize_t priority = 0;
- for (ModuleID module : modules) {
+ for (ModuleID module : modules)
module_priorities[module] = priority++;
- }
if (m_compiler_instance->getPreprocessor().getExternalSource()) {
m_compiler_instance->getPreprocessor()
@@ -455,9 +446,8 @@ void ClangModulesDeclVendorImpl::ForEachMacro(
.getExternalIdentifierLookup()) {
lookup->get(mi->first->getName());
}
- if (!ii) {
+ if (!ii)
ii = mi->first;
- }
}
ssize_t found_priority = -1;
@@ -504,24 +494,21 @@ void ClangModulesDeclVendorImpl::ForEachMacro(
for (auto pi = macro_info->param_begin(),
pe = macro_info->param_end();
pi != pe; ++pi) {
- if (!first_arg) {
+ if (!first_arg)
macro_expansion.append(", ");
- } else {
+ else
first_arg = false;
- }
macro_expansion.append((*pi)->getName().str());
}
if (macro_info->isC99Varargs()) {
- if (first_arg) {
+ if (first_arg)
macro_expansion.append("...");
- } else {
+ else
macro_expansion.append(", ...");
- }
- } else if (macro_info->isGNUVarargs()) {
+ } else if (macro_info->isGNUVarargs())
macro_expansion.append("...");
- }
macro_expansion.append(")");
}
@@ -533,11 +520,10 @@ void ClangModulesDeclVendorImpl::ForEachMacro(
for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
te = macro_info->tokens_end();
ti != te; ++ti) {
- if (!first_token) {
+ if (!first_token)
macro_expansion.append(" ");
- } else {
+ else
first_token = false;
- }
if (ti->isLiteral()) {
if (const char *literal_data = ti->getLiteralData()) {
@@ -718,7 +704,7 @@ ClangModulesDeclVendor::Create(Target &target) {
if (!instance->hasTarget())
return nullptr;
- instance->getTarget().adjust(instance->getLangOpts());
+ instance->getTarget().adjust(*diagnostics_engine, instance->getLangOpts());
if (!action->BeginSourceFile(*instance,
instance->getFrontendOpts().Inputs[0]))
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 42afac9edb0d..13d6a37113b8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -8,6 +8,7 @@
#include "ClangPersistentVariables.h"
#include "ClangASTImporter.h"
+#include "ClangModulesDeclVendor.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Value.h"
@@ -23,8 +24,10 @@
using namespace lldb;
using namespace lldb_private;
-ClangPersistentVariables::ClangPersistentVariables()
- : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang) {}
+ClangPersistentVariables::ClangPersistentVariables(
+ std::shared_ptr<Target> target_sp)
+ : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
+ m_target_sp(target_sp) {}
ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
const lldb::ValueObjectSP &valobj_sp) {
@@ -109,6 +112,15 @@ ClangPersistentVariables::GetClangASTImporter() {
return m_ast_importer_sp;
}
+std::shared_ptr<ClangModulesDeclVendor>
+ClangPersistentVariables::GetClangModulesDeclVendor() {
+ if (!m_modules_decl_vendor_sp) {
+ m_modules_decl_vendor_sp.reset(
+ ClangModulesDeclVendor::Create(*m_target_sp.get()));
+ }
+ return m_modules_decl_vendor_sp;
+}
+
ConstString
ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) {
llvm::SmallString<64> name;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index f888b2d56e68..b8a359d05f75 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -19,6 +19,8 @@
namespace lldb_private {
class ClangASTImporter;
+class ClangModulesDeclVendor;
+class Target;
class TypeSystemClang;
/// \class ClangPersistentVariables ClangPersistentVariables.h
@@ -30,7 +32,7 @@ class TypeSystemClang;
/// 0-based counter for naming result variables.
class ClangPersistentVariables : public PersistentExpressionState {
public:
- ClangPersistentVariables();
+ ClangPersistentVariables(std::shared_ptr<Target> target_sp);
~ClangPersistentVariables() override = default;
@@ -40,6 +42,7 @@ public:
}
std::shared_ptr<ClangASTImporter> GetClangASTImporter();
+ std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();
lldb::ExpressionVariableSP
CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override;
@@ -106,6 +109,8 @@ private:
///these are the highest-
///< priority source for macros.
std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
+ std::shared_ptr<ClangModulesDeclVendor> m_modules_decl_vendor_sp;
+ std::shared_ptr<Target> m_target_sp;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 9be294750fa0..1b205b13113b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -8,7 +8,7 @@
#include "lldb/Host/Config.h"
-#include <stdio.h>
+#include <cstdio>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -90,7 +90,7 @@ ClangUserExpression::ClangUserExpression(
}
}
-ClangUserExpression::~ClangUserExpression() {}
+ClangUserExpression::~ClangUserExpression() = default;
void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -349,10 +349,6 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man
static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target,
DiagnosticManager &diagnostic_manager) {
- ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor();
- if (!decl_vendor)
- return;
-
if (!target->GetEnableAutoImportClangModules())
return;
@@ -361,6 +357,11 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target,
if (!persistent_state)
return;
+ std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+ persistent_state->GetClangModulesDeclVendor();
+ if (!decl_vendor)
+ return;
+
StackFrame *frame = exe_ctx.GetFramePtr();
if (!frame)
return;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 9788a4e1c183..a78116352c2e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -14,7 +14,7 @@
#include "ClangExpressionSourceCode.h"
#include "ClangPersistentVariables.h"
-#include <stdio.h>
+#include <cstdio>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -34,21 +34,38 @@ using namespace lldb_private;
char ClangUtilityFunction::ID;
-/// Constructor
-///
-/// \param[in] text
-/// The text of the function. Must be a full translation unit.
-///
-/// \param[in] name
-/// The name of the function, as used in the text.
ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
- std::string text, std::string name)
+ std::string text, std::string name,
+ bool enable_debugging)
: UtilityFunction(
exe_scope,
- std::string(ClangExpressionSourceCode::g_expression_prefix) + text,
- std::move(name)) {}
+ std::string(ClangExpressionSourceCode::g_expression_prefix) + text +
+ std::string(ClangExpressionSourceCode::g_expression_suffix),
+ std::move(name), enable_debugging) {
+ // Write the source code to a file so that LLDB's source manager can display
+ // it when debugging the code.
+ if (enable_debugging) {
+ int temp_fd = -1;
+ llvm::SmallString<128> result_path;
+ llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
+ if (temp_fd != -1) {
+ lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true);
+ text = "#line 1 \"" + std::string(result_path) + "\"\n" + text;
+ size_t bytes_written = text.size();
+ file.Write(text.c_str(), bytes_written);
+ if (bytes_written == text.size()) {
+ // If we successfully wrote the source to a temporary file, replace the
+ // function text with the next text containing the line directive.
+ m_function_text =
+ std::string(ClangExpressionSourceCode::g_expression_prefix) + text +
+ std::string(ClangExpressionSourceCode::g_expression_suffix);
+ }
+ file.Close();
+ }
+ }
+}
-ClangUtilityFunction::~ClangUtilityFunction() {}
+ClangUtilityFunction::~ClangUtilityFunction() = default;
/// Install the utility function into a process
///
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index 7914e1406cd0..b8a154b3baed 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -48,8 +48,11 @@ public:
///
/// \param[in] name
/// The name of the function, as used in the text.
+ ///
+ /// \param[in] enable_debugging
+ /// Enable debugging of this function.
ClangUtilityFunction(ExecutionContextScope &exe_scope, std::string text,
- std::string name);
+ std::string name, bool enable_debugging);
~ClangUtilityFunction() override;
@@ -71,9 +74,9 @@ public:
private:
class ClangUtilityFunctionHelper : public ClangExpressionHelper {
public:
- ClangUtilityFunctionHelper() {}
+ ClangUtilityFunctionHelper() = default;
- ~ClangUtilityFunctionHelper() override {}
+ ~ClangUtilityFunctionHelper() override = default;
/// Return the object that the parser should use when resolving external
/// values. May be NULL if everything should be self-contained.
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index b984db43fa6d..425106bba0a3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -59,7 +59,7 @@ public:
/// Creates a configuration by analyzing the given list of used source files.
explicit CppModuleConfiguration(const FileSpecList &support_files);
/// Creates an empty and invalid configuration.
- CppModuleConfiguration() {}
+ CppModuleConfiguration() = default;
/// Returns true iff this is a valid configuration that can be used to
/// load and compile modules.
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
index f953e860969c..74dd04600b4b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
@@ -33,6 +33,9 @@ CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target)
"shared_ptr",
"unique_ptr",
"weak_ptr",
+ // iterator
+ "move_iterator",
+ "__wrap_iter",
// utility
"allocator",
"pair",
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index b35bf07034bd..5655d548ee34 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -14,6 +14,7 @@
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
@@ -41,14 +42,12 @@
using namespace llvm;
-static char ID;
-
typedef SmallVector<Instruction *, 2> InstrList;
IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
: m_maker(maker), m_values() {}
-IRForTarget::FunctionValueCache::~FunctionValueCache() {}
+IRForTarget::FunctionValueCache::~FunctionValueCache() = default;
llvm::Value *
IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
@@ -72,13 +71,9 @@ IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
lldb_private::IRExecutionUnit &execution_unit,
lldb_private::Stream &error_stream,
const char *func_name)
- : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
- m_module(nullptr), m_decl_map(decl_map),
- m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr),
- m_objc_getClass(nullptr), m_intptr_ty(nullptr),
- m_error_stream(error_stream), m_execution_unit(execution_unit),
- m_result_store(nullptr), m_result_is_pointer(false),
- m_reloc_placeholder(nullptr),
+ : m_resolve_vars(resolve_vars), m_func_name(func_name),
+ m_decl_map(decl_map), m_error_stream(error_stream),
+ m_execution_unit(execution_unit),
m_entry_instruction_finder(FindEntryInstruction) {}
/* Handy utility functions used at several places in the code */
@@ -105,8 +100,6 @@ static std::string PrintType(const llvm::Type *type, bool truncate = false) {
return s;
}
-IRForTarget::~IRForTarget() {}
-
bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
llvm_function.setLinkage(GlobalValue::ExternalLinkage);
@@ -1582,20 +1575,14 @@ bool IRForTarget::UnfoldConstant(Constant *old_constant,
FunctionValueCache get_element_pointer_maker(
[&value_maker, &entry_instruction_finder, old_constant,
constant_expr](llvm::Function *function) -> llvm::Value * {
- Value *ptr = constant_expr->getOperand(0);
+ auto *gep = cast<llvm::GEPOperator>(constant_expr);
+ Value *ptr = gep->getPointerOperand();
if (ptr == old_constant)
ptr = value_maker.GetValue(function);
std::vector<Value *> index_vector;
-
- unsigned operand_index;
- unsigned num_operands = constant_expr->getNumOperands();
-
- for (operand_index = 1; operand_index < num_operands;
- ++operand_index) {
- Value *operand = constant_expr->getOperand(operand_index);
-
+ for (Value *operand : gep->indices()) {
if (operand == old_constant)
operand = value_maker.GetValue(function);
@@ -1605,7 +1592,7 @@ bool IRForTarget::UnfoldConstant(Constant *old_constant,
ArrayRef<Value *> indices(index_vector);
return GetElementPtrInst::Create(
- nullptr, ptr, indices, "",
+ gep->getSourceElementType(), ptr, indices, "",
llvm::cast<Instruction>(
entry_instruction_finder.GetValue(function)));
});
@@ -1788,7 +1775,8 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
ConstantInt *offset_int(
ConstantInt::get(offset_type, offset, true));
GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
- nullptr, argument, offset_int, "", entry_instruction);
+ argument->getType()->getPointerElementType(), argument,
+ offset_int, "", entry_instruction);
if (name == m_result_name && !m_result_is_pointer) {
BitCastInst *bit_cast = new BitCastInst(
@@ -2022,10 +2010,3 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
return true;
}
-
-void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
- PassManagerType pass_mgr_type) {}
-
-PassManagerType IRForTarget::getPotentialPassManagerType() const {
- return PMT_ModulePassManager;
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index ebfc0cae626c..5f212fa8f918 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -58,7 +58,7 @@ class IRMemoryMap;
/// transformations to the IR which make it relocatable. These
/// transformations are discussed in more detail next to their relevant
/// functions.
-class IRForTarget : public llvm::ModulePass {
+class IRForTarget {
public:
enum class LookupResult { Success, Fail, Ignore };
@@ -87,9 +87,6 @@ public:
lldb_private::Stream &error_stream,
const char *func_name = "$__lldb_expr");
- /// Destructor
- ~IRForTarget() override;
-
/// Run this IR transformer on a single module
///
/// Implementation of the llvm::ModulePass::runOnModule() function.
@@ -101,20 +98,7 @@ public:
///
/// \return
/// True on success; false otherwise
- bool runOnModule(llvm::Module &llvm_module) override;
-
- /// Interface stub
- ///
- /// Implementation of the llvm::ModulePass::assignPassManager() function.
- void assignPassManager(llvm::PMStack &pass_mgr_stack,
- llvm::PassManagerType pass_mgr_type =
- llvm::PMT_ModulePassManager) override;
-
- /// Returns PMT_ModulePassManager
- ///
- /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
- /// function.
- llvm::PassManagerType getPotentialPassManagerType() const override;
+ bool runOnModule(llvm::Module &llvm_module);
private:
/// Ensures that the current function's linkage is set to external.
@@ -419,51 +403,46 @@ private:
/// True on success; false otherwise
bool ReplaceVariables(llvm::Function &llvm_function);
- /// Flags
- bool m_resolve_vars; ///< True if external variable references and persistent
- ///variable references should be resolved
- lldb_private::ConstString
- m_func_name; ///< The name of the function to translate
- lldb_private::ConstString
- m_result_name; ///< The name of the result variable ($0, $1, ...)
- lldb_private::TypeFromParser
- m_result_type; ///< The type of the result variable.
- llvm::Module *m_module; ///< The module being processed, or NULL if that has
- ///not been determined yet.
- std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the
- ///module being processed, or
- ///NULL if there is no
- ///module.
- lldb_private::ClangExpressionDeclMap
- *m_decl_map; ///< The DeclMap containing the Decls
- llvm::FunctionCallee
- m_CFStringCreateWithBytes; ///< The address of the function
- /// CFStringCreateWithBytes, cast to the
- /// appropriate function pointer type
- llvm::FunctionCallee m_sel_registerName; ///< The address of the function
- /// sel_registerName, cast to the
- /// appropriate function pointer type
- llvm::FunctionCallee m_objc_getClass; ///< The address of the function
- /// objc_getClass, cast to the
- /// appropriate function pointer type
- llvm::IntegerType
- *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
- lldb_private::Stream
- &m_error_stream; ///< The stream on which errors should be printed
- lldb_private::IRExecutionUnit &
- m_execution_unit; ///< The execution unit containing the IR being created.
-
- llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that
- ///writes to the result variable. If
- /// m_has_side_effects is true, this is
- /// NULL.
- bool m_result_is_pointer; ///< True if the function's result in the AST is a
- ///pointer (see comments in
- /// ASTResultSynthesizer::SynthesizeBodyResult)
-
+ /// True if external variable references and persistent variable references
+ /// should be resolved
+ bool m_resolve_vars;
+ /// The name of the function to translate
+ lldb_private::ConstString m_func_name;
+ /// The name of the result variable ($0, $1, ...)
+ lldb_private::ConstString m_result_name;
+ /// The type of the result variable.
+ lldb_private::TypeFromParser m_result_type;
+ /// The module being processed, or NULL if that has not been determined yet.
+ llvm::Module *m_module = nullptr;
+ /// The target data for the module being processed, or NULL if there is no
+ /// module.
+ std::unique_ptr<llvm::DataLayout> m_target_data;
+ /// The DeclMap containing the Decls
+ lldb_private::ClangExpressionDeclMap *m_decl_map;
+ /// The address of the function CFStringCreateWithBytes, cast to the
+ /// appropriate function pointer type
+ llvm::FunctionCallee m_CFStringCreateWithBytes;
+ /// The address of the function sel_registerName, cast to the appropriate
+ /// function pointer type.
+ llvm::FunctionCallee m_sel_registerName;
+ /// The address of the function objc_getClass, cast to the appropriate
+ /// function pointer type.
+ llvm::FunctionCallee m_objc_getClass;
+ /// The type of an integer large enough to hold a pointer.
+ llvm::IntegerType *m_intptr_ty = nullptr;
+ /// The stream on which errors should be printed.
+ lldb_private::Stream &m_error_stream;
+ /// The execution unit containing the IR being created.
+ lldb_private::IRExecutionUnit &m_execution_unit;
+ /// If non-NULL, the store instruction that writes to the result variable. If
+ /// m_has_side_effects is true, this is NULL.
+ llvm::StoreInst *m_result_store = nullptr;
+ /// True if the function's result in the AST is a pointer (see comments in
+ /// ASTResultSynthesizer::SynthesizeBodyResult)
+ bool m_result_is_pointer = false;
/// A placeholder that will be replaced by a pointer to the final location of
/// the static allocation.
- llvm::GlobalVariable *m_reloc_placeholder;
+ llvm::GlobalVariable *m_reloc_placeholder = nullptr;
class FunctionValueCache {
public:
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 555912780df9..bf0bbdab740f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stdlib.h>
+#include <cstdlib>
#include "EmulateInstructionARM.h"
#include "EmulationStateARM.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index d15d80c97e38..dfd7c926dabf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -19,8 +19,8 @@ namespace lldb_private {
// ITSession - Keep track of the IT Block progression.
class ITSession {
public:
- ITSession() : ITCounter(0), ITState(0) {}
- ~ITSession() {}
+ ITSession() = default;
+ ~ITSession() = default;
// InitIT - Initializes ITCounter/ITState.
bool InitIT(uint32_t bits7_0);
@@ -39,8 +39,8 @@ public:
uint32_t GetCond();
private:
- uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4.
- uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
+ uint32_t ITCounter = 0; // Possible values: 0, 1, 2, 3, 4.
+ uint32_t ITState = 0; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
};
class EmulateInstructionARM : public EmulateInstruction {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index aef08baa8ae9..569482c7b23b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -20,11 +20,11 @@
using namespace lldb;
using namespace lldb_private;
-EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
+EmulationStateARM::EmulationStateARM() : m_vfp_regs(), m_memory() {
ClearPseudoRegisters();
}
-EmulationStateARM::~EmulationStateARM() {}
+EmulationStateARM::~EmulationStateARM() = default;
bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
RegisterContext *reg_ctx = frame.GetRegisterContext().get();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
index 955c7c642058..28bc5d98649d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -61,7 +61,7 @@ public:
const lldb_private::RegisterValue &reg_value);
private:
- uint32_t m_gpr[17];
+ uint32_t m_gpr[17] = {0};
struct _sd_regs {
uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index d4cb726fc7e5..a1a93c0b5a5f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -8,7 +8,7 @@
#include "EmulateInstructionMIPS.h"
-#include <stdlib.h>
+#include <cstdlib>
#include "lldb/Core/Address.h"
#include "lldb/Core/Opcode.h"
@@ -159,8 +159,8 @@ EmulateInstructionMIPS::EmulateInstructionMIPS(
target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
assert(m_asm_info.get() && m_subtype_info.get());
- m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
- m_reg_info.get(), nullptr);
+ m_context = std::make_unique<llvm::MCContext>(
+ triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get());
assert(m_context.get());
m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
@@ -1018,8 +1018,9 @@ bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
const size_t bytes_read =
target->ReadMemory(next_addr, /* Address of next instruction */
- true, /* prefer_file_cache */
- buf, sizeof(uint32_t), error, &load_addr);
+ buf, sizeof(uint32_t), error,
+ false, /* force_live_memory */
+ &load_addr);
if (bytes_read == 0)
return true;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 4ccaf0de0758..6044d00c0cbf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -8,7 +8,7 @@
#include "EmulateInstructionMIPS64.h"
-#include <stdlib.h>
+#include <cstdlib>
#include "lldb/Core/Address.h"
#include "lldb/Core/Opcode.h"
@@ -163,8 +163,8 @@ EmulateInstructionMIPS64::EmulateInstructionMIPS64(
target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
assert(m_asm_info.get() && m_subtype_info.get());
- m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
- m_reg_info.get(), nullptr);
+ m_context = std::make_unique<llvm::MCContext>(
+ triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get());
assert(m_context.get());
m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
index 5d97513c0be7..4e78c369c128 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
@@ -8,7 +8,7 @@
#include "EmulateInstructionPPC64.h"
-#include <stdlib.h>
+#include <cstdlib>
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/UnwindPlan.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
index 99784bd3dbd1..9a88b343878c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
@@ -127,7 +127,7 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData(
StackFrameSP responsible_frame;
for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) {
StackFrameSP frame = thread_sp->GetStackFrameAtIndex(I);
- Address addr = frame->GetFrameCodeAddress();
+ Address addr = frame->GetFrameCodeAddressForSymbolication();
if (addr.GetModule() == runtime_module_sp) // Skip PCs from the runtime.
continue;
@@ -135,11 +135,6 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData(
if (!responsible_frame)
responsible_frame = frame;
- // First frame in stacktrace should point to a real PC, not return address.
- if (I != 0 && trace->GetSize() == 0) {
- addr.Slide(-1);
- }
-
lldb::addr_t PC = addr.GetLoadAddress(&target);
trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC)));
}
@@ -271,8 +266,11 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo(
info->GetObjectForDotSeparatedPath("tid");
tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
- HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs);
- ThreadSP new_thread_sp(history_thread);
+ // We gather symbolication addresses above, so no need for HistoryThread to
+ // try to infer the call addresses.
+ bool pcs_are_call_addresses = true;
+ ThreadSP new_thread_sp = std::make_shared<HistoryThread>(
+ *process_sp, tid, PCs, pcs_are_call_addresses);
// Save this in the Process' ExtendedThreadList so a strong pointer retains
// the object
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
index b60eb53f3d4a..58bc38a551f0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
@@ -29,7 +29,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
-#include <ctype.h>
+#include <cctype>
#include <memory>
@@ -150,8 +150,8 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData(
StructuredData::Array *trace = new StructuredData::Array();
auto trace_sp = StructuredData::ObjectSP(trace);
for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) {
- const Address FCA =
- thread_sp->GetStackFrameAtIndex(I)->GetFrameCodeAddress();
+ const Address FCA = thread_sp->GetStackFrameAtIndex(I)
+ ->GetFrameCodeAddressForSymbolication();
if (FCA.GetModule() == runtime_module_sp) // Skip PCs from the runtime.
continue;
@@ -324,8 +324,11 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
info->GetObjectForDotSeparatedPath("tid");
tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
- HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs);
- ThreadSP new_thread_sp(history_thread);
+ // We gather symbolication addresses above, so no need for HistoryThread to
+ // try to infer the call addresses.
+ bool pcs_are_call_addresses = true;
+ ThreadSP new_thread_sp = std::make_shared<HistoryThread>(
+ *process_sp, tid, PCs, pcs_are_call_addresses);
std::string stop_reason_description = GetStopReasonDescription(info);
new_thread_sp->SetName(stop_reason_description.c_str());
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 35788a6445c2..1c498a2ddc11 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -74,14 +74,12 @@ public:
const CompilerType reserved_type =
clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
const char *const FuncPtr_name("__FuncPtr");
- const CompilerType FuncPtr_type =
- clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
m_block_struct_type = clang_ast_context->CreateStructForIdentifier(
ConstString(), {{isa_name, isa_type},
{flags_name, flags_type},
{reserved_name, reserved_type},
- {FuncPtr_name, FuncPtr_type}});
+ {FuncPtr_name, function_pointer_type}});
}
~BlockPointerSyntheticFrontEnd() override = default;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index d844498fd8a3..895fd55f499c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -59,6 +59,11 @@ lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
return g_name;
}
+bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
+ const char *mangled_name = mangled.GetMangledName().GetCString();
+ return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name);
+}
+
// PluginInterface protocol
lldb_private::ConstString CPlusPlusLanguage::GetPluginName() {
@@ -1054,7 +1059,7 @@ CPlusPlusLanguage::GetHardcodedSummaries() {
.SetSkipReferences(false),
lldb_private::formatters::VectorTypeSummaryProvider,
"vector_type pointer summary provider"));
- if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
+ if (valobj.GetCompilerType().IsVectorType()) {
if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
return formatter_sp;
}
@@ -1074,7 +1079,7 @@ CPlusPlusLanguage::GetHardcodedSummaries() {
.SetSkipReferences(false),
lldb_private::formatters::BlockPointerSummaryProvider,
"block pointer summary provider"));
- if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
+ if (valobj.GetCompilerType().IsBlockPointerType()) {
return formatter_sp;
}
return nullptr;
@@ -1104,7 +1109,7 @@ CPlusPlusLanguage::GetHardcodedSynthetics() {
.SetNonCacheable(true),
"vector_type synthetic children",
lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
- if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
+ if (valobj.GetCompilerType().IsVectorType()) {
if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
return formatter_sp;
}
@@ -1123,7 +1128,7 @@ CPlusPlusLanguage::GetHardcodedSynthetics() {
.SetNonCacheable(true),
"block pointer synthetic children",
lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
- if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
+ if (valobj.GetCompilerType().IsBlockPointerType()) {
return formatter_sp;
}
return nullptr;
@@ -1147,7 +1152,7 @@ bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
".h", ".hh", ".hpp", ".hxx", ".h++"};
for (auto suffix : suffixes) {
- if (file_path.endswith_lower(suffix))
+ if (file_path.endswith_insensitive(suffix))
return true;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index e2b5d2918753..9163be4807ec 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -28,8 +28,7 @@ public:
class MethodName {
public:
MethodName()
- : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers(),
- m_parsed(false), m_parse_error(false) {}
+ : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers() {}
MethodName(ConstString s)
: m_full(s), m_basename(), m_context(), m_arguments(), m_qualifiers(),
@@ -68,8 +67,8 @@ public:
llvm::StringRef m_context; // Decl context: "lldb::SBTarget"
llvm::StringRef m_arguments; // Arguments: "(unsigned int)"
llvm::StringRef m_qualifiers; // Qualifiers: "const"
- bool m_parsed;
- bool m_parse_error;
+ bool m_parsed = false;
+ bool m_parse_error = false;
};
CPlusPlusLanguage() = default;
@@ -105,6 +104,8 @@ public:
static lldb_private::ConstString GetPluginNameStatic();
+ bool SymbolNameFitsToLanguage(Mangled mangled) const override;
+
static bool IsCPPMangledName(llvm::StringRef name);
// Extract C++ context and identifier from a string using heuristic matching
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
index 6fe6b12725b0..426434c48608 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
@@ -69,7 +69,7 @@ private:
size_t begin_index = 0;
size_t end_index = 0;
- Range() {}
+ Range() = default;
Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {
assert(end >= begin);
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 2b16ebe79daf..8eda422f3145 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -379,8 +379,7 @@ lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator(
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), m_count_sp(),
- m_weak_count_sp(), m_ptr_size(0), m_byte_order(lldb::eByteOrderInvalid) {
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr) {
if (valobj_sp)
Update();
}
@@ -403,42 +402,23 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
if (idx == 0)
return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
- if (idx > 2)
- return lldb::ValueObjectSP();
-
if (idx == 1) {
- if (!m_count_sp) {
- ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(
- ConstString("__shared_owners_"), true));
- if (!shared_owners_sp)
- return lldb::ValueObjectSP();
- uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
- DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
- m_count_sp = CreateValueObjectFromData(
- "count", data, valobj_sp->GetExecutionContextRef(),
- shared_owners_sp->GetCompilerType());
- }
- return m_count_sp;
- } else /* if (idx == 2) */
- {
- if (!m_weak_count_sp) {
- ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(
- ConstString("__shared_weak_owners_"), true));
- if (!shared_weak_owners_sp)
- return lldb::ValueObjectSP();
- uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
- DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
- m_weak_count_sp = CreateValueObjectFromData(
- "count", data, valobj_sp->GetExecutionContextRef(),
- shared_weak_owners_sp->GetCompilerType());
+ if (auto ptr_sp =
+ valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)) {
+ Status status;
+ auto value_sp = ptr_sp->Dereference(status);
+ if (status.Success()) {
+ auto value_type_sp =
+ valobj_sp->GetCompilerType().GetTypeTemplateArgument(0);
+ return value_sp->Cast(value_type_sp);
+ }
}
- return m_weak_count_sp;
}
+
+ return lldb::ValueObjectSP();
}
bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
- m_count_sp.reset();
- m_weak_count_sp.reset();
m_cntrl = nullptr;
ValueObjectSP valobj_sp = m_backend.GetSP();
@@ -449,9 +429,6 @@ bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
if (!target_sp)
return false;
- m_byte_order = target_sp->GetArchitecture().GetByteOrder();
- m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize();
-
lldb::ValueObjectSP cntrl_sp(
valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true));
@@ -469,10 +446,8 @@ size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name) {
if (name == "__ptr_")
return 0;
- if (name == "count")
+ if (name == "$$dereference$$")
return 1;
- if (name == "weak_count")
- return 2;
return UINT32_MAX;
}
@@ -488,7 +463,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator(
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() {
+ : SyntheticChildrenFrontEnd(*valobj_sp) {
if (valobj_sp)
Update();
}
@@ -505,19 +480,27 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator(
size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
CalculateNumChildren() {
- return (m_compressed_pair_sp ? 1 : 0);
+ return (m_value_ptr_sp ? 1 : 0);
}
lldb::ValueObjectSP
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex(
size_t idx) {
- if (!m_compressed_pair_sp)
+ if (!m_value_ptr_sp)
return lldb::ValueObjectSP();
- if (idx != 0)
- return lldb::ValueObjectSP();
+ if (idx == 0)
+ return m_value_ptr_sp;
- return m_compressed_pair_sp;
+ if (idx == 1) {
+ Status status;
+ auto value_sp = m_value_ptr_sp->Dereference(status);
+ if (status.Success()) {
+ return value_sp;
+ }
+ }
+
+ return lldb::ValueObjectSP();
}
bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
@@ -530,7 +513,7 @@ bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
if (!ptr_sp)
return false;
- m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
+ m_value_ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
return false;
}
@@ -544,6 +527,8 @@ size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name) {
if (name == "__value_")
return 0;
+ if (name == "$$dereference$$")
+ return 1;
return UINT32_MAX;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index ea5a7c178178..99e206543197 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -105,10 +105,6 @@ public:
private:
ValueObject *m_cntrl;
- lldb::ValueObjectSP m_count_sp;
- lldb::ValueObjectSP m_weak_count_sp;
- uint8_t m_ptr_size;
- lldb::ByteOrder m_byte_order;
};
class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
@@ -128,7 +124,7 @@ public:
~LibcxxUniquePtrSyntheticFrontEnd() override;
private:
- lldb::ValueObjectSP m_compressed_pair_sp;
+ lldb::ValueObjectSP m_value_ptr_sp;
};
SyntheticChildrenFrontEnd *
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 6de4637a6a4a..e5b868fc0fce 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -85,7 +85,7 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
CompilerType type;
ValueObjectSP chunk;
// For small bitsets __first_ is not an array, but a plain size_t.
- if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) {
+ if (m_first->GetCompilerType().IsArrayType(&type)) {
llvm::Optional<uint64_t> bit_size =
type.GetBitSize(ctx.GetBestExecutionContextScope());
if (!bit_size || *bit_size == 0)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 0d5ae16a0b29..47c6634ed65e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -27,8 +27,7 @@ namespace {
class ListEntry {
public:
ListEntry() = default;
- ListEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
- ListEntry(const ListEntry &rhs) = default;
+ ListEntry(ValueObjectSP entry_sp) : m_entry_sp(std::move(entry_sp)) {}
ListEntry(ValueObject *entry)
: m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
@@ -73,9 +72,8 @@ private:
class ListIterator {
public:
ListIterator() = default;
- ListIterator(ListEntry entry) : m_entry(entry) {}
- ListIterator(ValueObjectSP entry) : m_entry(entry) {}
- ListIterator(const ListIterator &rhs) = default;
+ ListIterator(ListEntry entry) : m_entry(std::move(entry)) {}
+ ListIterator(ValueObjectSP entry) : m_entry(std::move(entry)) {}
ListIterator(ValueObject *entry) : m_entry(entry) {}
ValueObjectSP value() { return m_entry.GetEntry(); }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index 64a199e24e4a..25c2bfd9387b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -26,7 +26,6 @@ class MapEntry {
public:
MapEntry() = default;
explicit MapEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
- MapEntry(const MapEntry &rhs) = default;
explicit MapEntry(ValueObject *entry)
: m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
@@ -86,9 +85,9 @@ class MapIterator {
public:
MapIterator() = default;
MapIterator(MapEntry entry, size_t depth = 0)
- : m_entry(entry), m_max_depth(depth), m_error(false) {}
+ : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {}
MapIterator(ValueObjectSP entry, size_t depth = 0)
- : m_entry(entry), m_max_depth(depth), m_error(false) {}
+ : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {}
MapIterator(const MapIterator &rhs)
: m_entry(rhs.m_entry), m_max_depth(rhs.m_max_depth), m_error(false) {}
MapIterator(ValueObject *entry, size_t depth = 0)
@@ -138,7 +137,7 @@ protected:
}
private:
- MapEntry tree_min(MapEntry &&x) {
+ MapEntry tree_min(MapEntry x) {
if (x.null())
return MapEntry();
MapEntry left(x.left());
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index 0b34b4e2fc89..79e864a2cbd5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -99,9 +99,17 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
if (ptr_obj)
m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
- ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
- if (del_obj)
- m_del_obj = del_obj->Clone(ConstString("deleter")).get();
+ // Add a 'deleter' child if there was a non-empty deleter type specified.
+ //
+ // The object might have size=1 in the TypeSystem but occupies no dedicated
+ // storage due to no_unique_address, so infer the actual size from the total
+ // size of the unique_ptr class. If sizeof(unique_ptr) == sizeof(void*) then
+ // the deleter is empty and should be hidden.
+ if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) {
+ ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
+ if (del_obj)
+ m_del_obj = del_obj->Clone(ConstString("deleter")).get();
+ }
if (m_ptr_obj) {
Status error;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
index d871d3470e70..1479f4f0c151 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -351,7 +351,7 @@ static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value,
}
static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream,
- uint64_t value, lldb::LanguageType lang) {
+ int64_t value, lldb::LanguageType lang) {
static ConstString g_TypeHint("NSNumber:long");
std::string prefix, suffix;
@@ -367,10 +367,10 @@ static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream,
}
static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream,
- const llvm::APInt &value,
- lldb::LanguageType lang) {
+ const llvm::APInt &value,
+ lldb::LanguageType lang) {
static ConstString g_TypeHint("NSNumber:int128_t");
-
+
std::string prefix, suffix;
if (Language *language = Language::FindPlugin(lang)) {
if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
@@ -379,11 +379,11 @@ static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream,
suffix.clear();
}
}
-
+
stream.PutCString(prefix.c_str());
const int radix = 10;
const bool isSigned = true;
- std::string str = value.toString(radix, isSigned);
+ std::string str = llvm::toString(value, radix, isSigned);
stream.PutCString(str.c_str());
stream.PutCString(suffix.c_str());
}
@@ -426,6 +426,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
if (!process_sp)
return false;
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
if (!runtime)
@@ -456,9 +457,18 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
return NSDecimalNumberSummaryProvider(valobj, stream, options);
if (class_name == "NSNumber" || class_name == "__NSCFNumber") {
- uint64_t value = 0;
+ int64_t value = 0;
uint64_t i_bits = 0;
- if (descriptor->GetTaggedPointerInfo(&i_bits, &value)) {
+ if (descriptor->GetTaggedPointerInfoSigned(&i_bits, &value)) {
+ // Check for "preserved" numbers. We still don't support them yet.
+ if (i_bits & 0x8) {
+ if (log)
+ log->Printf(
+ "Unsupported (preserved) NSNumber tagged pointer 0x%" PRIu64,
+ valobj_addr);
+ return false;
+ }
+
switch (i_bits) {
case 0:
NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
@@ -498,49 +508,66 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
f64 = 0x5,
sint128 = 0x6
};
-
+
uint64_t data_location = valobj_addr + 2 * ptr_size;
TypeCodes type_code;
-
+
if (new_format) {
- uint64_t cfinfoa =
- process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
- ptr_size, 0, error);
-
+ uint64_t cfinfoa = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + ptr_size, ptr_size, 0, error);
+
if (error.Fail())
return false;
bool is_preserved_number = cfinfoa & 0x8;
if (is_preserved_number) {
- lldbassert(!static_cast<bool>("We should handle preserved numbers!"));
+ if (log)
+ log->Printf(
+ "Unsupported preserved NSNumber tagged pointer 0x%" PRIu64,
+ valobj_addr);
return false;
}
type_code = static_cast<TypeCodes>(cfinfoa & 0x7);
} else {
- uint8_t data_type =
- process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1,
- 0, error) & 0x1F;
-
+ uint8_t data_type = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + ptr_size, 1, 0, error) &
+ 0x1F;
+
if (error.Fail())
return false;
-
+
switch (data_type) {
- case 1: type_code = TypeCodes::sint8; break;
- case 2: type_code = TypeCodes::sint16; break;
- case 3: type_code = TypeCodes::sint32; break;
- case 17: data_location += 8; LLVM_FALLTHROUGH;
- case 4: type_code = TypeCodes::sint64; break;
- case 5: type_code = TypeCodes::f32; break;
- case 6: type_code = TypeCodes::f64; break;
- default: return false;
+ case 1:
+ type_code = TypeCodes::sint8;
+ break;
+ case 2:
+ type_code = TypeCodes::sint16;
+ break;
+ case 3:
+ type_code = TypeCodes::sint32;
+ break;
+ case 17:
+ data_location += 8;
+ LLVM_FALLTHROUGH;
+ case 4:
+ type_code = TypeCodes::sint64;
+ break;
+ case 5:
+ type_code = TypeCodes::f32;
+ break;
+ case 6:
+ type_code = TypeCodes::f64;
+ break;
+ default:
+ return false;
}
}
-
+
uint64_t value = 0;
bool success = false;
switch (type_code) {
- case TypeCodes::sint8:
+ case TypeCodes::sint8:
value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0,
error);
if (error.Fail())
@@ -548,7 +575,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
success = true;
break;
- case TypeCodes::sint16:
+ case TypeCodes::sint16:
value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0,
error);
if (error.Fail())
@@ -573,8 +600,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
success = true;
break;
- case TypeCodes::f32:
- {
+ case TypeCodes::f32: {
uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
data_location, 4, 0, error);
if (error.Fail())
@@ -585,8 +611,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
success = true;
break;
}
- case TypeCodes::f64:
- {
+ case TypeCodes::f64: {
uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
data_location, 8, 0, error);
if (error.Fail())
@@ -600,16 +625,17 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
case TypeCodes::sint128: // internally, this is the same
{
uint64_t words[2];
- words[1] = process_sp->ReadUnsignedIntegerFromMemory(
- data_location, 8, 0, error);
+ words[1] = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8,
+ 0, error);
if (error.Fail())
return false;
- words[0] = process_sp->ReadUnsignedIntegerFromMemory(
- data_location + 8, 8, 0, error);
+ words[0] = process_sp->ReadUnsignedIntegerFromMemory(data_location + 8,
+ 8, 0, error);
if (error.Fail())
return false;
llvm::APInt i128_value(128, words);
- NSNumber_FormatInt128(valobj, stream, i128_value, options.GetLanguage());
+ NSNumber_FormatInt128(valobj, stream, i128_value,
+ options.GetLanguage());
success = true;
break;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
index efc80cc75557..a862da551813 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -13,7 +13,7 @@
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
-#include <inttypes.h>
+#include <cinttypes>
using namespace lldb;
using namespace lldb_private;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index afb9c6951f55..326f47a10660 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -410,6 +410,7 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
static const ConstString g_DictionaryM("__NSDictionaryM");
static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable");
+ static const ConstString g_DictionaryMFrozen("__NSFrozenDictionaryM");
static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
static const ConstString g_Dictionary0("__NSDictionary0");
static const ConstString g_DictionaryCF("__CFDictionary");
@@ -427,7 +428,8 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
+ } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy
+ || class_name == g_DictionaryMFrozen) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
@@ -509,6 +511,7 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
static const ConstString g_DictionaryM("__NSDictionaryM");
static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable");
+ static const ConstString g_DictionaryMFrozen("__NSFrozenDictionaryM");
static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
static const ConstString g_Dictionary0("__NSDictionary0");
static const ConstString g_DictionaryCF("__CFDictionary");
@@ -520,7 +523,7 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
if (class_name == g_DictionaryI) {
return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
- } else if (class_name == g_DictionaryM) {
+ } else if (class_name == g_DictionaryM || class_name == g_DictionaryMFrozen) {
if (runtime->GetFoundationVersion() >= 1437) {
return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp));
} else if (runtime->GetFoundationVersion() >= 1428) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
index a15b0f64954a..068bca9e7b94 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -209,14 +209,13 @@ protected:
m_process = nullptr;
}
- InlinedIndexes()
- : m_indexes(0), m_count(0), m_ptr_size(0), m_process(nullptr) {}
+ InlinedIndexes() {}
private:
- uint64_t m_indexes;
- size_t m_count;
- uint32_t m_ptr_size;
- Process *m_process;
+ uint64_t m_indexes = 0;
+ size_t m_count = 0;
+ uint32_t m_ptr_size = 0;
+ Process *m_process = nullptr;
// cfr. Foundation for the details of this code
size_t _lengthForInlinePayload(uint32_t ptr_size) {
@@ -271,10 +270,10 @@ protected:
m_count = 0;
}
- OutsourcedIndexes() : m_indexes(nullptr), m_count(0) {}
+ OutsourcedIndexes() {}
- ValueObject *m_indexes;
- size_t m_count;
+ ValueObject *m_indexes = nullptr;
+ size_t m_count = 0;
};
union {
@@ -288,9 +287,9 @@ protected:
m_outsourced.Clear();
}
- Impl() : m_mode(Mode::Invalid) {}
+ Impl() {}
- Mode m_mode;
+ Mode m_mode = Mode::Invalid;
} m_impl;
uint32_t m_ptr_size;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp
index 4dbbe6fbddff..43ef7b694bbe 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp
@@ -444,18 +444,12 @@ bool lldb_private::formatters::NSSetISyntheticFrontEnd::Update() {
if (!valobj_sp)
return false;
m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- if (valobj_sp->IsPointerType()) {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
if (!process_sp)
return false;
m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+ Status error;
if (m_ptr_size == 4) {
m_data_32 = new DataDescriptor_32();
process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
@@ -728,18 +722,12 @@ lldb_private::formatters::
if (!valobj_sp)
return false;
m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- if (valobj_sp->IsPointerType()) {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
if (!process_sp)
return false;
m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+ Status error;
if (m_ptr_size == 4) {
m_data_32 = new D32();
process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 29391daaab93..379c53432b7b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -225,14 +225,17 @@ ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
return ConstString();
}
-std::vector<ConstString>
+std::vector<Language::MethodNameVariant>
ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
- std::vector<ConstString> variant_names;
+ std::vector<Language::MethodNameVariant> variant_names;
ObjCLanguage::MethodName objc_method(method_name.GetCString(), false);
if (!objc_method.IsValid(false)) {
return variant_names;
}
+ variant_names.emplace_back(objc_method.GetSelector(),
+ lldb::eFunctionNameTypeSelector);
+
const bool is_class_method =
objc_method.GetType() == MethodName::eTypeClassMethod;
const bool is_instance_method =
@@ -242,31 +245,43 @@ ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
if (is_class_method || is_instance_method) {
if (name_sans_category)
- variant_names.emplace_back(name_sans_category);
+ variant_names.emplace_back(name_sans_category,
+ lldb::eFunctionNameTypeFull);
} else {
StreamString strm;
strm.Printf("+%s", objc_method.GetFullName().GetCString());
- variant_names.emplace_back(strm.GetString());
+ variant_names.emplace_back(ConstString(strm.GetString()),
+ lldb::eFunctionNameTypeFull);
strm.Clear();
strm.Printf("-%s", objc_method.GetFullName().GetCString());
- variant_names.emplace_back(strm.GetString());
+ variant_names.emplace_back(ConstString(strm.GetString()),
+ lldb::eFunctionNameTypeFull);
strm.Clear();
if (name_sans_category) {
strm.Printf("+%s", name_sans_category.GetCString());
- variant_names.emplace_back(strm.GetString());
+ variant_names.emplace_back(ConstString(strm.GetString()),
+ lldb::eFunctionNameTypeFull);
strm.Clear();
strm.Printf("-%s", name_sans_category.GetCString());
- variant_names.emplace_back(strm.GetString());
+ variant_names.emplace_back(ConstString(strm.GetString()),
+ lldb::eFunctionNameTypeFull);
}
}
return variant_names;
}
+bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
+ ConstString demangled_name = mangled.GetDemangledName();
+ if (!demangled_name)
+ return false;
+ return ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString());
+}
+
static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
if (!objc_category_sp)
return;
@@ -990,8 +1005,11 @@ std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
bool result = false;
if (auto *target = exe_scope->CalculateTarget().get()) {
- if (auto *clang_modules_decl_vendor =
- target->GetClangModulesDeclVendor()) {
+ auto *persistent_vars = llvm::cast<ClangPersistentVariables>(
+ target->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC));
+ if (std::shared_ptr<ClangModulesDeclVendor> clang_modules_decl_vendor =
+ persistent_vars->GetClangModulesDeclVendor()) {
ConstString key_cs(key);
auto types = clang_modules_decl_vendor->FindTypes(
key_cs, /*max_matches*/ UINT32_MAX);
@@ -1116,7 +1134,7 @@ bool ObjCLanguage::IsNilReference(ValueObject &valobj) {
bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {
const auto suffixes = {".h", ".m", ".M"};
for (auto suffix : suffixes) {
- if (file_path.endswith_lower(suffix))
+ if (file_path.endswith_insensitive(suffix))
return true;
}
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index 02c15e86046b..691c51883c8a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -27,9 +27,7 @@ public:
public:
enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
- MethodName()
- : m_full(), m_class(), m_category(), m_selector(),
- m_type(eTypeUnspecified), m_category_is_valid(false) {}
+ MethodName() : m_full(), m_class(), m_category(), m_selector() {}
MethodName(const char *name, bool strict)
: m_full(), m_class(), m_category(), m_selector(),
@@ -81,8 +79,8 @@ public:
m_class_category; // Class with category: "NSString(my_additions)"
ConstString m_category; // Category: "my_additions"
ConstString m_selector; // Selector: "myStringWithCString:"
- Type m_type;
- bool m_category_is_valid;
+ Type m_type = eTypeUnspecified;
+ bool m_category_is_valid = false;
};
ObjCLanguage() = default;
@@ -102,9 +100,12 @@ public:
// variant_names[1] => "-[NSString(my_additions) myStringWithCString:]"
// variant_names[2] => "+[NSString myStringWithCString:]"
// variant_names[3] => "-[NSString myStringWithCString:]"
- std::vector<ConstString>
+ // Also returns the FunctionNameType of each possible name.
+ std::vector<Language::MethodNameVariant>
GetMethodNameVariants(ConstString method_name) const override;
+ bool SymbolNameFitsToLanguage(Mangled mangled) const override;
+
lldb::TypeCategoryImplSP GetFormatters() override;
std::vector<ConstString>
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
index 0a4017eda434..359978553210 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
@@ -19,7 +19,7 @@ LLDB_PLUGIN_DEFINE(ObjCPlusPlusLanguage)
bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
const auto suffixes = {".h", ".mm"};
for (auto suffix : suffixes) {
- if (file_path.endswith_lower(suffix))
+ if (file_path.endswith_insensitive(suffix))
return true;
}
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index 24ab9cc5f238..bed2a98067e6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <string.h>
+#include <cstring>
#include <memory>
@@ -322,6 +322,9 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
}
}
+ if (symbol == nullptr)
+ return optional_info;
+
// Case 1 or 3
if (scl.GetSize() >= 1) {
optional_info = line_entry_helper(target, scl[0], symbol,
@@ -397,8 +400,8 @@ CPPLanguageRuntime::GetStepThroughTrampolinePlan(Thread &thread,
// We create a ThreadPlan to keep stepping through using the address range
// of the current function.
ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
- thread, range_of_curr_func, sc, eOnlyThisThread, eLazyBoolYes,
- eLazyBoolYes);
+ thread, range_of_curr_func, sc, nullptr, eOnlyThisThread,
+ eLazyBoolYes, eLazyBoolYes);
return ret_plan_sp;
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 6ea9751f563a..f5b587c51960 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -196,7 +196,7 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
//
class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
+ value_type = Value::ValueType::Scalar;
// Only a pointer or reference type can have a different dynamic and static
// type:
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index bdd5c29db848..405b8a6f16b7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -252,6 +252,7 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process,
}
bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
+ lldb::addr_t relative_selector_base_addr,
bool is_small, bool has_direct_sel) {
size_t ptr_size = process->GetAddressByteSize();
size_t size = GetSize(process, is_small);
@@ -281,6 +282,8 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
0, error);
if (!error.Success())
return false;
+ } else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) {
+ m_name_ptr = relative_selector_base_addr + nameref_offset;
}
m_types_ptr = addr + 4 + types_offset;
m_imp_ptr = addr + 8 + imp_offset;
@@ -389,14 +392,14 @@ bool ClassDescriptorV2::Describe(
if (base_method_list->m_entsize != method_t::GetSize(process, is_small))
return false;
- std::unique_ptr<method_t> method;
- method = std::make_unique<method_t>();
-
+ std::unique_ptr<method_t> method = std::make_unique<method_t>();
+ lldb::addr_t relative_selector_base_addr =
+ m_runtime.GetRelativeSelectorBaseAddr();
for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) {
method->Read(process,
base_method_list->m_first_ptr +
(i * base_method_list->m_entsize),
- is_small, has_direct_selector);
+ relative_selector_base_addr, is_small, has_direct_selector);
if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
break;
@@ -514,8 +517,7 @@ uint64_t ClassDescriptorV2::GetInstanceSize() {
return 0;
}
-ClassDescriptorV2::iVarsStorage::iVarsStorage()
- : m_filled(false), m_ivars(), m_mutex() {}
+ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {}
size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); }
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 9ef21c6e7208..7ba957940ae7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -41,6 +41,12 @@ public:
return false;
}
+ bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+ int64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) override {
+ return false;
+ }
+
uint64_t GetInstanceSize() override;
ObjCLanguageRuntime::ObjCISA GetISA() override { return m_objc_class_ptr; }
@@ -71,16 +77,14 @@ private:
static const uint32_t RW_REALIZED = (1 << 31);
struct objc_class_t {
- ObjCLanguageRuntime::ObjCISA m_isa; // The class's metaclass.
- ObjCLanguageRuntime::ObjCISA m_superclass;
- lldb::addr_t m_cache_ptr;
- lldb::addr_t m_vtable_ptr;
- lldb::addr_t m_data_ptr;
- uint8_t m_flags;
+ ObjCLanguageRuntime::ObjCISA m_isa = 0; // The class's metaclass.
+ ObjCLanguageRuntime::ObjCISA m_superclass = 0;
+ lldb::addr_t m_cache_ptr = 0;
+ lldb::addr_t m_vtable_ptr = 0;
+ lldb::addr_t m_data_ptr = 0;
+ uint8_t m_flags = 0;
- objc_class_t()
- : m_isa(0), m_superclass(0), m_cache_ptr(0), m_vtable_ptr(0),
- m_data_ptr(0), m_flags(0) {}
+ objc_class_t() = default;
void Clear() {
m_isa = 0;
@@ -162,7 +166,8 @@ private:
+ field_size; // IMP imp;
}
- bool Read(Process *process, lldb::addr_t addr, bool, bool);
+ bool Read(Process *process, lldb::addr_t addr,
+ lldb::addr_t relative_method_lists_base_addr, bool, bool);
};
struct ivar_list_t {
@@ -207,7 +212,7 @@ private:
void fill(AppleObjCRuntimeV2 &runtime, ClassDescriptorV2 &descriptor);
private:
- bool m_filled;
+ bool m_filled = false;
std::vector<iVarDescriptor> m_ivars;
std::recursive_mutex m_mutex;
};
@@ -253,7 +258,7 @@ public:
ClassDescriptorV2Tagged(
ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp,
- uint64_t payload) {
+ uint64_t u_payload, int64_t s_payload) {
if (!actual_class_sp) {
m_valid = false;
return;
@@ -264,9 +269,10 @@ public:
return;
}
m_valid = true;
- m_payload = payload;
+ m_payload = u_payload;
m_info_bits = (m_payload & 0x0FULL);
m_value_bits = (m_payload & ~0x0FULL) >> 4;
+ m_value_bits_signed = (s_payload & ~0x0FLL) >> 4;
}
~ClassDescriptorV2Tagged() override = default;
@@ -308,6 +314,18 @@ public:
return true;
}
+ bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+ int64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) override {
+ if (info_bits)
+ *info_bits = GetInfoBits();
+ if (value_bits)
+ *value_bits = GetValueBitsSigned();
+ if (payload)
+ *payload = GetPayload();
+ return true;
+ }
+
uint64_t GetInstanceSize() override {
return (IsValid() ? m_pointer_size : 0);
}
@@ -319,6 +337,10 @@ public:
// these calls are not part of any formal tagged pointers specification
virtual uint64_t GetValueBits() { return (IsValid() ? m_value_bits : 0); }
+ virtual int64_t GetValueBitsSigned() {
+ return (IsValid() ? m_value_bits_signed : 0);
+ }
+
virtual uint64_t GetInfoBits() { return (IsValid() ? m_info_bits : 0); }
virtual uint64_t GetPayload() { return (IsValid() ? m_payload : 0); }
@@ -329,6 +351,7 @@ private:
bool m_valid;
uint64_t m_info_bits;
uint64_t m_value_bits;
+ int64_t m_value_bits_signed;
uint64_t m_payload;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 7b331307c0f7..9bc40c16e5d0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -59,7 +59,7 @@ public:
clang::DeclContext::lookup_result result =
non_const_interface_decl->lookup(name);
- return (result.size() != 0);
+ return (!result.empty());
} while (false);
SetNoExternalVisibleDeclsForName(decl_ctx, name);
@@ -555,7 +555,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
if (!lookup_result.empty()) {
if (clang::ObjCInterfaceDecl *result_iface_decl =
- llvm::dyn_cast<clang::ObjCInterfaceDecl>(lookup_result[0])) {
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.begin())) {
if (log) {
clang::QualType result_iface_type =
ast_ctx.getObjCInterfaceType(result_iface_decl);
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 973a5570c06e..88e86c51fe44 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -48,7 +48,7 @@ LLDB_PLUGIN_DEFINE(AppleObjCRuntime)
char AppleObjCRuntime::ID = 0;
-AppleObjCRuntime::~AppleObjCRuntime() {}
+AppleObjCRuntime::~AppleObjCRuntime() = default;
AppleObjCRuntime::AppleObjCRuntime(Process *process)
: ObjCLanguageRuntime(process), m_read_objc_library(false),
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index b37e5a9a7bf9..98d0e9cf991b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -49,7 +49,7 @@ bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress(
TypeAndOrName &class_type_or_name, Address &address,
Value::ValueType &value_type) {
class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
+ value_type = Value::ValueType::Scalar;
if (CouldHaveDynamicValue(in_value)) {
auto class_descriptor(GetClassDescriptor(in_value));
if (class_descriptor && class_descriptor->IsValid() &&
@@ -339,8 +339,6 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
if (!objc_module_sp)
return;
- uint32_t isa_count = 0;
-
lldb::addr_t hash_table_ptr = GetISAHashTablePointer();
if (hash_table_ptr != LLDB_INVALID_ADDRESS) {
// Read the NXHashTable struct:
@@ -383,8 +381,6 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
if (bucket_isa_count == 0)
continue;
- isa_count += bucket_isa_count;
-
ObjCISA isa;
if (bucket_isa_count == 1) {
// When we only have one entry in the bucket, the bucket data
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index 4eb7d979394b..12ee2cc53639 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -64,6 +64,12 @@ public:
return false;
}
+ bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+ int64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) override {
+ return false;
+ }
+
uint64_t GetInstanceSize() override { return m_instance_size; }
ObjCISA GetISA() override { return m_isa; }
@@ -120,8 +126,7 @@ protected:
class HashTableSignature {
public:
- HashTableSignature()
- : m_count(0), m_num_buckets(0), m_buckets_ptr(LLDB_INVALID_ADDRESS) {}
+ HashTableSignature() = default;
bool NeedsUpdate(uint32_t count, uint32_t num_buckets,
lldb::addr_t buckets_ptr) {
@@ -137,9 +142,9 @@ protected:
}
protected:
- uint32_t m_count;
- uint32_t m_num_buckets;
- lldb::addr_t m_buckets_ptr;
+ uint32_t m_count = 0;
+ uint32_t m_num_buckets = 0;
+ lldb::addr_t m_buckets_ptr = LLDB_INVALID_ADDRESS;
};
lldb::addr_t GetISAHashTablePointer();
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index ee84ccd869fc..10512a97ad69 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stdint.h>
+#include <cstdint>
#include <memory>
#include <string>
@@ -39,6 +39,7 @@
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
@@ -75,8 +76,7 @@ char AppleObjCRuntimeV2::ID = 0;
static const char *g_get_dynamic_class_info_name =
"__lldb_apple_objc_v2_get_dynamic_class_info";
-// Testing using the new C++11 raw string literals. If this breaks GCC then we
-// will need to revert to the code above...
+
static const char *g_get_dynamic_class_info_body = R"(
extern "C"
@@ -121,14 +121,20 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr
if (grc)
{
const unsigned num_classes = grc->num_classes;
+ DEBUG_PRINTF ("num_classes = %u\n", grc->num_classes);
if (class_infos_ptr)
{
+ const unsigned num_buckets_minus_one = grc->num_buckets_minus_one;
+ DEBUG_PRINTF ("num_buckets_minus_one = %u\n", num_buckets_minus_one);
+
const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+ DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
+
ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
BucketInfo *buckets = (BucketInfo *)grc->buckets;
-
+
uint32_t idx = 0;
- for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i)
+ for (unsigned i=0; i<=num_buckets_minus_one; ++i)
{
if (buckets[i].name_ptr != NX_MAPNOTAKEY)
{
@@ -140,6 +146,7 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr
h = ((h << 5) + h) + c;
class_infos[idx].hash = h;
class_infos[idx].isa = buckets[i].isa;
+ DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, buckets[i].name_ptr);
}
++idx;
}
@@ -157,6 +164,75 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr
)";
+static const char *g_get_dynamic_class_info2_name =
+ "__lldb_apple_objc_v2_get_dynamic_class_info2";
+
+static const char *g_get_dynamic_class_info2_body = R"(
+
+extern "C" {
+ int printf(const char * format, ...);
+ void free(void *ptr);
+ Class* objc_copyRealizedClassList_nolock(unsigned int *outCount);
+ const char* objc_debug_class_getNameRaw(Class cls);
+}
+
+#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
+
+struct ClassInfo
+{
+ Class isa;
+ uint32_t hash;
+} __attribute__((__packed__));
+
+uint32_t
+__lldb_apple_objc_v2_get_dynamic_class_info2(void *gdb_objc_realized_classes_ptr,
+ void *class_infos_ptr,
+ uint32_t class_infos_byte_size,
+ uint32_t should_log)
+{
+ DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
+ DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
+
+ const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+ DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
+
+ ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+
+ uint32_t count = 0;
+ Class* realized_class_list = objc_copyRealizedClassList_nolock(&count);
+ DEBUG_PRINTF ("count = %u\n", count);
+
+ uint32_t idx = 0;
+ for (uint32_t i=0; i<=count; ++i)
+ {
+ if (idx < max_class_infos)
+ {
+ Class isa = realized_class_list[i];
+ const char *name_ptr = objc_debug_class_getNameRaw(isa);
+ if (name_ptr == NULL)
+ continue;
+ const char *s = name_ptr;
+ uint32_t h = 5381;
+ for (unsigned char c = *s; c; c = *++s)
+ h = ((h << 5) + h) + c;
+ class_infos[idx].hash = h;
+ class_infos[idx].isa = isa;
+ DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name_ptr);
+ }
+ idx++;
+ }
+
+ if (idx < max_class_infos)
+ {
+ class_infos[idx].isa = NULL;
+ class_infos[idx].hash = 0;
+ }
+
+ free(realized_class_list);
+ return count;
+}
+)";
+
// We'll substitute in class_getName or class_getNameRaw depending
// on which is present.
static const char *g_shared_cache_class_name_funcptr = R"(
@@ -169,8 +245,7 @@ extern "C"
static const char *g_get_shared_cache_class_info_name =
"__lldb_apple_objc_v2_get_shared_cache_class_info";
-// Testing using the new C++11 raw string literals. If this breaks GCC then we
-// will need to revert to the code above...
+
static const char *g_get_shared_cache_class_info_body = R"(
extern "C"
@@ -188,6 +263,12 @@ struct objc_classheader_t {
int32_t hiOffset;
};
+struct objc_classheader_v16_t {
+ uint64_t isDuplicate : 1,
+ objectCacheOffset : 47, // Offset from the shared cache base
+ dylibObjCIndex : 16;
+};
+
struct objc_clsopt_t {
uint32_t capacity;
uint32_t occupied;
@@ -205,6 +286,22 @@ struct objc_clsopt_t {
// objc_classheader_t duplicateOffsets[duplicateCount];
};
+struct objc_clsopt_v16_t {
+ uint32_t version;
+ uint32_t capacity;
+ uint32_t occupied;
+ uint32_t shift;
+ uint32_t mask;
+ uint64_t salt;
+ uint32_t scramble[256];
+ uint8_t tab[0]; // tab[mask+1]
+ // uint8_t checkbytes[capacity];
+ // int32_t offset[capacity];
+ // objc_classheader_t clsOffsets[capacity];
+ // uint32_t duplicateCount;
+ // objc_classheader_t duplicateOffsets[duplicateCount];
+};
+
struct objc_opt_t {
uint32_t version;
int32_t selopt_offset;
@@ -220,6 +317,20 @@ struct objc_opt_v14_t {
int32_t clsopt_offset;
};
+struct objc_opt_v16_t {
+ uint32_t version;
+ uint32_t flags;
+ int32_t selopt_offset;
+ int32_t headeropt_ro_offset;
+ int32_t unused_clsopt_offset;
+ int32_t unused_protocolopt_offset;
+ int32_t headeropt_rw_offset;
+ int32_t unused_protocolopt2_offset;
+ int32_t largeSharedCachesClassOffset;
+ int32_t largeSharedCachesProtocolOffset;
+ uint64_t relativeMethodSelectorBaseAddressCacheOffset;
+};
+
struct ClassInfo
{
Class isa;
@@ -228,20 +339,33 @@ struct ClassInfo
uint32_t
__lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
+ void *shared_cache_base_ptr,
void *class_infos_ptr,
+ uint64_t *relative_selector_offset,
uint32_t class_infos_byte_size,
uint32_t should_log)
{
+ *relative_selector_offset = 0;
uint32_t idx = 0;
DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
+ DEBUG_PRINTF ("shared_cache_base_ptr = %p\n", shared_cache_base_ptr);
DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
DEBUG_PRINTF ("class_infos_byte_size = %u (%llu class infos)\n", class_infos_byte_size, (uint64_t)(class_infos_byte_size/sizeof(ClassInfo)));
if (objc_opt_ro_ptr)
{
const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
const objc_opt_v14_t* objc_opt_v14 = (objc_opt_v14_t*)objc_opt_ro_ptr;
- const bool is_v14_format = objc_opt->version >= 14;
- if (is_v14_format)
+ const objc_opt_v16_t* objc_opt_v16 = (objc_opt_v16_t*)objc_opt_ro_ptr;
+ if (objc_opt->version >= 16)
+ {
+ *relative_selector_offset = objc_opt_v16->relativeMethodSelectorBaseAddressCacheOffset;
+ DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v16->version);
+ DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v16->flags);
+ DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt_v16->selopt_offset);
+ DEBUG_PRINTF ("objc_opt->headeropt_ro_offset = %d\n", objc_opt_v16->headeropt_ro_offset);
+ DEBUG_PRINTF ("objc_opt->relativeMethodSelectorBaseAddressCacheOffset = %d\n", *relative_selector_offset);
+ }
+ else if (objc_opt->version >= 14)
{
DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v14->version);
DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v14->flags);
@@ -256,10 +380,126 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
}
- if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14 || objc_opt->version == 15)
+
+ if (objc_opt->version == 16)
+ {
+ const objc_clsopt_v16_t* clsopt = (const objc_clsopt_v16_t*)((uint8_t *)objc_opt + objc_opt_v16->largeSharedCachesClassOffset);
+ const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+
+ DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
+
+ ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+
+ const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
+ const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
+ const objc_classheader_v16_t *classOffsets = (const objc_classheader_v16_t *)(offsets + clsopt->capacity);
+
+ DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
+ DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
+ DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
+
+ for (uint32_t i=0; i<clsopt->capacity; ++i)
+ {
+ const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
+ DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
+
+ if (classOffsets[i].isDuplicate) {
+ DEBUG_PRINTF("isDuplicate = true\n");
+ continue; // duplicate
+ }
+
+ if (objectCacheOffset == 0) {
+ DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
+ continue; // invalid offset
+ }
+
+ if (class_infos && idx < max_class_infos)
+ {
+ class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
+
+ // Lookup the class name.
+ const char *name = class_name_lookup_func(class_infos[idx].isa);
+ DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+
+ // Hash the class name so we don't have to read it.
+ const char *s = name;
+ uint32_t h = 5381;
+ for (unsigned char c = *s; c; c = *++s)
+ {
+ // class_getName demangles swift names and the hash must
+ // be calculated on the mangled name. hash==0 means lldb
+ // will fetch the mangled name and compute the hash in
+ // ParseClassInfoArray.
+ if (c == '.')
+ {
+ h = 0;
+ break;
+ }
+ h = ((h << 5) + h) + c;
+ }
+ class_infos[idx].hash = h;
+ }
+ else
+ {
+ DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
+ }
+ ++idx;
+ }
+
+ const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
+ const uint32_t duplicate_count = *duplicate_count_ptr;
+ const objc_classheader_v16_t *duplicateClassOffsets = (const objc_classheader_v16_t *)(&duplicate_count_ptr[1]);
+
+ DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
+ DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
+
+ for (uint32_t i=0; i<duplicate_count; ++i)
+ {
+ const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
+ DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
+
+ if (classOffsets[i].isDuplicate) {
+ DEBUG_PRINTF("isDuplicate = true\n");
+ continue; // duplicate
+ }
+
+ if (objectCacheOffset == 0) {
+ DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
+ continue; // invalid offset
+ }
+
+ if (class_infos && idx < max_class_infos)
+ {
+ class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
+
+ // Lookup the class name.
+ const char *name = class_name_lookup_func(class_infos[idx].isa);
+ DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+
+ // Hash the class name so we don't have to read it.
+ const char *s = name;
+ uint32_t h = 5381;
+ for (unsigned char c = *s; c; c = *++s)
+ {
+ // class_getName demangles swift names and the hash must
+ // be calculated on the mangled name. hash==0 means lldb
+ // will fetch the mangled name and compute the hash in
+ // ParseClassInfoArray.
+ if (c == '.')
+ {
+ h = 0;
+ break;
+ }
+ h = ((h << 5) + h) + c;
+ }
+ class_infos[idx].hash = h;
+ }
+ }
+ }
+ else if (objc_opt->version >= 12 && objc_opt->version <= 15)
{
const objc_clsopt_t* clsopt = NULL;
- if (is_v14_format)
+ if (objc_opt->version >= 14)
clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt_v14 + objc_opt_v14->clsopt_offset);
else
clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
@@ -291,7 +531,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
DEBUG_PRINTF("clsOffset == invalidEntryOffset\n");
continue; // invalid offset
}
-
+
if (class_infos && idx < max_class_infos)
{
class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
@@ -321,7 +561,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
}
++idx;
}
-
+
const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
const uint32_t duplicate_count = *duplicate_count_ptr;
const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);
@@ -334,7 +574,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
continue; // duplicate
else if (clsOffset == invalidEntryOffset)
continue; // invalid offset
-
+
if (class_infos && idx < max_class_infos)
{
class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
@@ -353,7 +593,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
{
h = 0;
break;
- }
+ }
h = ((h << 5) + h) + c;
}
class_infos[idx].hash = h;
@@ -380,55 +620,57 @@ ExtractRuntimeGlobalSymbol(Process *process, ConstString name,
error.SetErrorString("no process");
return default_value;
}
+
if (!module_sp) {
error.SetErrorString("no module");
return default_value;
}
+
if (!byte_size)
byte_size = process->GetAddressByteSize();
const Symbol *symbol =
module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
- if (symbol && symbol->ValueIsAddress()) {
- lldb::addr_t symbol_load_addr =
- symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
- if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
- if (read_value)
- return process->ReadUnsignedIntegerFromMemory(
- symbol_load_addr, byte_size, default_value, error);
- else
- return symbol_load_addr;
- } else {
- error.SetErrorString("symbol address invalid");
- return default_value;
- }
- } else {
+
+ if (!symbol || !symbol->ValueIsAddress()) {
error.SetErrorString("no symbol");
return default_value;
}
+
+ lldb::addr_t symbol_load_addr =
+ symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
+ if (symbol_load_addr == LLDB_INVALID_ADDRESS) {
+ error.SetErrorString("symbol address invalid");
+ return default_value;
+ }
+
+ if (read_value)
+ return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size,
+ default_value, error);
+ return symbol_load_addr;
}
static void RegisterObjCExceptionRecognizer(Process *process);
AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
const ModuleSP &objc_module_sp)
- : AppleObjCRuntime(process), m_get_class_info_code(),
- m_get_class_info_args(LLDB_INVALID_ADDRESS),
- m_get_class_info_args_mutex(), m_get_shared_cache_class_info_code(),
- m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
- m_get_shared_cache_class_info_args_mutex(), m_decl_vendor_up(),
+ : AppleObjCRuntime(process), m_objc_module_sp(objc_module_sp),
+ m_dynamic_class_info_extractor(*this),
+ m_shared_cache_class_info_extractor(*this), m_decl_vendor_up(),
m_tagged_pointer_obfuscator(LLDB_INVALID_ADDRESS),
- m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS), m_hash_signature(),
- m_has_object_getClass(false), m_loaded_objc_opt(false),
- m_non_pointer_isa_cache_up(
- NonPointerISACache::CreateInstance(*this, objc_module_sp)),
+ m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
+ m_relative_selector_base(LLDB_INVALID_ADDRESS), m_hash_signature(),
+ m_has_object_getClass(false), m_has_objc_copyRealizedClassList(false),
+ m_loaded_objc_opt(false), m_non_pointer_isa_cache_up(),
m_tagged_pointer_vendor_up(
TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
m_encoding_to_type_sp(), m_noclasses_warning_emitted(false),
- m_CFBoolean_values() {
+ m_CFBoolean_values(), m_realized_class_generation_count(0) {
static const ConstString g_gdb_object_getClass("gdb_object_getClass");
- m_has_object_getClass =
- (objc_module_sp->FindFirstSymbolWithNameAndType(
- g_gdb_object_getClass, eSymbolTypeCode) != nullptr);
+ m_has_object_getClass = HasSymbol(g_gdb_object_getClass);
+ static const ConstString g_objc_copyRealizedClassList(
+ "_ZL33objc_copyRealizedClassList_nolockPj");
+ m_has_objc_copyRealizedClassList = HasSymbol(g_objc_copyRealizedClassList);
+
RegisterObjCExceptionRecognizer(process);
}
@@ -451,7 +693,7 @@ bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
assert(in_value.GetTargetSP().get() == m_process->CalculateTarget().get());
class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
+ value_type = Value::ValueType::Scalar;
// Make sure we can have a dynamic value before starting...
if (CouldHaveDynamicValue(in_value)) {
@@ -498,15 +740,21 @@ LanguageRuntime *AppleObjCRuntimeV2::CreateInstance(Process *process,
if (AppleObjCRuntime::GetObjCVersion(process, objc_module_sp) ==
ObjCRuntimeVersions::eAppleObjC_V2)
return new AppleObjCRuntimeV2(process, objc_module_sp);
- else
- return nullptr;
- } else
return nullptr;
+ }
+ return nullptr;
}
static constexpr OptionDefinition g_objc_classtable_dump_options[] = {
- {LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument,
- nullptr, {}, 0, eArgTypeNone,
+ {LLDB_OPT_SET_ALL,
+ false,
+ "verbose",
+ 'v',
+ OptionParser::eNoArgument,
+ nullptr,
+ {},
+ 0,
+ eArgTypeNone,
"Print ivar and method information in detail"}};
class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed {
@@ -548,12 +796,13 @@ public:
};
CommandObjectObjC_ClassTable_Dump(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "dump", "Dump information on Objective-C classes "
- "known to the current process.",
- "language objc class-table dump",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused),
+ : CommandObjectParsed(interpreter, "dump",
+ "Dump information on Objective-C classes "
+ "known to the current process.",
+ "language objc class-table dump",
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
m_options() {
CommandArgumentEntry arg;
CommandArgumentData index_arg;
@@ -581,8 +830,8 @@ protected:
case 0:
break;
case 1: {
- regex_up = std::make_unique<RegularExpression>(
- llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0)));
+ regex_up =
+ std::make_unique<RegularExpression>(command.GetArgumentAtIndex(0));
if (!regex_up->IsValid()) {
result.AppendError(
"invalid argument - please provide a valid regular expression");
@@ -632,6 +881,7 @@ protected:
ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
ivar.m_size, ivar.m_offset);
}
+
iterator->second->Describe(
nullptr,
[&std_out](const char *name, const char *type) -> bool {
@@ -655,11 +905,10 @@ protected:
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
return true;
- } else {
- result.AppendError("current process has no Objective-C runtime loaded");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
}
+ result.AppendError("current process has no Objective-C runtime loaded");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
}
CommandOptions m_options;
@@ -741,11 +990,10 @@ protected:
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
return true;
- } else {
- result.AppendError("current process has no Objective-C runtime loaded");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
}
+ result.AppendError("current process has no Objective-C runtime loaded");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
}
};
@@ -951,11 +1199,7 @@ bool AppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr) {
class RemoteNXMapTable {
public:
- RemoteNXMapTable()
- : m_count(0), m_num_buckets_minus_one(0),
- m_buckets_ptr(LLDB_INVALID_ADDRESS), m_process(nullptr),
- m_end_iterator(*this, -1), m_load_addr(LLDB_INVALID_ADDRESS),
- m_map_pair_size(0), m_invalid_key(0) {}
+ RemoteNXMapTable() : m_end_iterator(*this, -1) {}
void Dump() {
printf("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
@@ -1129,18 +1373,17 @@ public:
private:
// contents of _NXMapTable struct
- uint32_t m_count;
- uint32_t m_num_buckets_minus_one;
- lldb::addr_t m_buckets_ptr;
- lldb_private::Process *m_process;
+ uint32_t m_count = 0;
+ uint32_t m_num_buckets_minus_one = 0;
+ lldb::addr_t m_buckets_ptr = LLDB_INVALID_ADDRESS;
+ lldb_private::Process *m_process = nullptr;
const_iterator m_end_iterator;
- lldb::addr_t m_load_addr;
- size_t m_map_pair_size;
- lldb::addr_t m_invalid_key;
+ lldb::addr_t m_load_addr = LLDB_INVALID_ADDRESS;
+ size_t m_map_pair_size = 0;
+ lldb::addr_t m_invalid_key = 0;
};
-AppleObjCRuntimeV2::HashTableSignature::HashTableSignature()
- : m_count(0), m_num_buckets(0), m_buckets_ptr(0) {}
+AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() = default;
void AppleObjCRuntimeV2::HashTableSignature::UpdateSignature(
const RemoteNXMapTable &hash_table) {
@@ -1171,8 +1414,8 @@ bool AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate(
ObjCLanguageRuntime::ClassDescriptorSP
AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) {
ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
- if (m_non_pointer_isa_cache_up)
- class_descriptor_sp = m_non_pointer_isa_cache_up->GetClassDescriptor(isa);
+ if (auto *non_pointer_isa_cache = GetNonPointerIsaCache())
+ class_descriptor_sp = non_pointer_isa_cache->GetClassDescriptor(isa);
if (!class_descriptor_sp)
class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
return class_descriptor_sp;
@@ -1214,11 +1457,9 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
objc_class_sp = GetClassDescriptorFromISA(isa);
if (isa && !objc_class_sp) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS |
- LIBLLDB_LOG_TYPES));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
LLDB_LOGF(log,
- "0x%" PRIx64
- ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
+ "0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
"not in class descriptor cache 0x%" PRIx64,
isa_pointer, isa);
}
@@ -1229,28 +1470,29 @@ lldb::addr_t AppleObjCRuntimeV2::GetTaggedPointerObfuscator() {
if (m_tagged_pointer_obfuscator != LLDB_INVALID_ADDRESS)
return m_tagged_pointer_obfuscator;
-
Process *process = GetProcess();
ModuleSP objc_module_sp(GetObjCModule());
if (!objc_module_sp)
return LLDB_INVALID_ADDRESS;
- static ConstString g_gdb_objc_obfuscator("objc_debug_taggedpointer_obfuscator");
+ static ConstString g_gdb_objc_obfuscator(
+ "objc_debug_taggedpointer_obfuscator");
const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
- g_gdb_objc_obfuscator, lldb::eSymbolTypeAny);
+ g_gdb_objc_obfuscator, lldb::eSymbolTypeAny);
if (symbol) {
lldb::addr_t g_gdb_obj_obfuscator_ptr =
- symbol->GetLoadAddress(&process->GetTarget());
+ symbol->GetLoadAddress(&process->GetTarget());
if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS) {
Status error;
- m_tagged_pointer_obfuscator = process->ReadPointerFromMemory(
- g_gdb_obj_obfuscator_ptr, error);
+ m_tagged_pointer_obfuscator =
+ process->ReadPointerFromMemory(g_gdb_obj_obfuscator_ptr, error);
}
}
- // If we don't have a correct value at this point, there must be no obfuscation.
+ // If we don't have a correct value at this point, there must be no
+ // obfuscation.
if (m_tagged_pointer_obfuscator == LLDB_INVALID_ADDRESS)
m_tagged_pointer_obfuscator = 0;
@@ -1284,11 +1526,212 @@ lldb::addr_t AppleObjCRuntimeV2::GetISAHashTablePointer() {
return m_isa_hash_table_ptr;
}
+std::unique_ptr<UtilityFunction>
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunctionImpl(
+ ExecutionContext &exe_ctx, std::string code, std::string name) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+
+ LLDB_LOG(log, "Creating utility function {0}", name);
+
+ TypeSystemClang *ast =
+ ScratchTypeSystemClang::GetForTarget(exe_ctx.GetTargetRef());
+ if (!ast)
+ return {};
+
+ auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
+ std::move(code), std::move(name), eLanguageTypeC, exe_ctx);
+ if (!utility_fn_or_error) {
+ LLDB_LOG_ERROR(
+ log, utility_fn_or_error.takeError(),
+ "Failed to get utility function for implementation lookup: {0}");
+ return {};
+ }
+
+ // Make some types for our arguments.
+ CompilerType clang_uint32_t_type =
+ ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ CompilerType clang_void_pointer_type =
+ ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ // Make the runner function for our implementation utility function.
+ ValueList arguments;
+ Value value;
+ value.SetValueType(Value::ValueType::Scalar);
+ value.SetCompilerType(clang_void_pointer_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+ value.SetValueType(Value::ValueType::Scalar);
+ value.SetCompilerType(clang_uint32_t_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
+
+ Status error;
+ utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
+ exe_ctx.GetThreadSP(), error);
+
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "Failed to make function caller for implementation lookup: {0}.",
+ error.AsCString());
+ return {};
+ }
+
+ return utility_fn;
+}
+
+UtilityFunction *
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunction(
+ ExecutionContext &exe_ctx, Helper helper) {
+ switch (helper) {
+ case gdb_objc_realized_classes: {
+ if (!m_gdb_objc_realized_classes_helper.utility_function)
+ m_gdb_objc_realized_classes_helper.utility_function =
+ GetClassInfoUtilityFunctionImpl(exe_ctx,
+ g_get_dynamic_class_info_body,
+ g_get_dynamic_class_info_name);
+ return m_gdb_objc_realized_classes_helper.utility_function.get();
+ }
+ case objc_copyRealizedClassList: {
+ if (!m_objc_copyRealizedClassList_helper.utility_function)
+ m_objc_copyRealizedClassList_helper.utility_function =
+ GetClassInfoUtilityFunctionImpl(exe_ctx,
+ g_get_dynamic_class_info2_body,
+ g_get_dynamic_class_info2_name);
+ return m_objc_copyRealizedClassList_helper.utility_function.get();
+ }
+ }
+ llvm_unreachable("Unexpected helper");
+}
+
+lldb::addr_t &
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoArgs(Helper helper) {
+ switch (helper) {
+ case gdb_objc_realized_classes:
+ return m_gdb_objc_realized_classes_helper.args;
+ case objc_copyRealizedClassList:
+ return m_objc_copyRealizedClassList_helper.args;
+ }
+ llvm_unreachable("Unexpected helper");
+}
+
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::Helper
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::ComputeHelper() const {
+ if (!m_runtime.m_has_objc_copyRealizedClassList)
+ return DynamicClassInfoExtractor::gdb_objc_realized_classes;
+
+ if (Process *process = m_runtime.GetProcess()) {
+ if (DynamicLoader *loader = process->GetDynamicLoader()) {
+ if (loader->IsFullyInitialized())
+ return DynamicClassInfoExtractor::objc_copyRealizedClassList;
+ }
+ }
+
+ return DynamicClassInfoExtractor::gdb_objc_realized_classes;
+}
+
+std::unique_ptr<UtilityFunction>
+AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::
+ GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+
+ LLDB_LOG(log, "Creating utility function {0}",
+ g_get_shared_cache_class_info_name);
+
+ TypeSystemClang *ast =
+ ScratchTypeSystemClang::GetForTarget(exe_ctx.GetTargetRef());
+ if (!ast)
+ return {};
+
+ // If the inferior objc.dylib has the class_getNameRaw function, use that in
+ // our jitted expression. Else fall back to the old class_getName.
+ static ConstString g_class_getName_symbol_name("class_getName");
+ static ConstString g_class_getNameRaw_symbol_name(
+ "objc_debug_class_getNameRaw");
+
+ ConstString class_name_getter_function_name =
+ m_runtime.HasSymbol(g_class_getNameRaw_symbol_name)
+ ? g_class_getNameRaw_symbol_name
+ : g_class_getName_symbol_name;
+
+ // Substitute in the correct class_getName / class_getNameRaw function name,
+ // concatenate the two parts of our expression text. The format string has
+ // two %s's, so provide the name twice.
+ std::string shared_class_expression;
+ llvm::raw_string_ostream(shared_class_expression)
+ << llvm::format(g_shared_cache_class_name_funcptr,
+ class_name_getter_function_name.AsCString(),
+ class_name_getter_function_name.AsCString());
+
+ shared_class_expression += g_get_shared_cache_class_info_body;
+
+ auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
+ std::move(shared_class_expression), g_get_shared_cache_class_info_name,
+ eLanguageTypeC, exe_ctx);
+
+ if (!utility_fn_or_error) {
+ LLDB_LOG_ERROR(
+ log, utility_fn_or_error.takeError(),
+ "Failed to get utility function for implementation lookup: {0}");
+ return nullptr;
+ }
+
+ // Make some types for our arguments.
+ CompilerType clang_uint32_t_type =
+ ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ CompilerType clang_void_pointer_type =
+ ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+ CompilerType clang_uint64_t_pointer_type =
+ ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64)
+ .GetPointerType();
+
+ // Next make the function caller for our implementation utility function.
+ ValueList arguments;
+ Value value;
+ value.SetValueType(Value::ValueType::Scalar);
+ value.SetCompilerType(clang_void_pointer_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ value.SetValueType(Value::ValueType::Scalar);
+ value.SetCompilerType(clang_uint64_t_pointer_type);
+ arguments.PushValue(value);
+
+ value.SetValueType(Value::ValueType::Scalar);
+ value.SetCompilerType(clang_uint32_t_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
+
+ Status error;
+ utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
+ exe_ctx.GetThreadSP(), error);
+
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "Failed to make function caller for implementation lookup: {0}.",
+ error.AsCString());
+ return {};
+ }
+
+ return utility_fn;
+}
+
+UtilityFunction *
+AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::GetClassInfoUtilityFunction(
+ ExecutionContext &exe_ctx) {
+ if (!m_utility_function)
+ m_utility_function = GetClassInfoUtilityFunctionImpl(exe_ctx);
+ return m_utility_function.get();
+}
+
AppleObjCRuntimeV2::DescriptorMapUpdateResult
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap(
RemoteNXMapTable &hash_table) {
- Process *process = GetProcess();
-
+ Process *process = m_runtime.GetProcess();
if (process == nullptr)
return DescriptorMapUpdateResult::Fail();
@@ -1316,65 +1759,36 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
Status err;
+ // Compute which helper we're going to use for this update.
+ const DynamicClassInfoExtractor::Helper helper = ComputeHelper();
+
// Read the total number of classes from the hash table
- const uint32_t num_classes = hash_table.GetCount();
+ const uint32_t num_classes =
+ helper == DynamicClassInfoExtractor::gdb_objc_realized_classes
+ ? hash_table.GetCount()
+ : m_runtime.m_realized_class_generation_count;
if (num_classes == 0) {
- LLDB_LOGF(log, "No dynamic classes found in gdb_objc_realized_classes.");
+ LLDB_LOGF(log, "No dynamic classes found.");
return DescriptorMapUpdateResult::Success(0);
}
- // Make some types for our arguments
- CompilerType clang_uint32_t_type =
- ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
- CompilerType clang_void_pointer_type =
- ast->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- ValueList arguments;
- FunctionCaller *get_class_info_function = nullptr;
-
- if (!m_get_class_info_code) {
- auto utility_fn_or_error = GetTargetRef().CreateUtilityFunction(
- g_get_dynamic_class_info_body, g_get_dynamic_class_info_name,
- eLanguageTypeC, exe_ctx);
- if (!utility_fn_or_error) {
- LLDB_LOG_ERROR(
- log, utility_fn_or_error.takeError(),
- "Failed to get utility function for implementation lookup: {0}");
- return DescriptorMapUpdateResult::Fail();
- }
- m_get_class_info_code = std::move(*utility_fn_or_error);
-
- // Next make the runner function for our implementation utility function.
- Value value;
- value.SetValueType(Value::eValueTypeScalar);
- value.SetCompilerType(clang_void_pointer_type);
- arguments.PushValue(value);
- arguments.PushValue(value);
-
- value.SetValueType(Value::eValueTypeScalar);
- value.SetCompilerType(clang_uint32_t_type);
- arguments.PushValue(value);
- arguments.PushValue(value);
+ UtilityFunction *get_class_info_code =
+ GetClassInfoUtilityFunction(exe_ctx, helper);
+ if (!get_class_info_code) {
+ // The callee will have already logged a useful error message.
+ return DescriptorMapUpdateResult::Fail();
+ }
- Status error;
- get_class_info_function = m_get_class_info_code->MakeFunctionCaller(
- clang_uint32_t_type, arguments, thread_sp, error);
+ FunctionCaller *get_class_info_function =
+ get_class_info_code->GetFunctionCaller();
- if (error.Fail()) {
- LLDB_LOGF(log,
- "Failed to make function caller for implementation lookup: %s.",
- error.AsCString());
- return DescriptorMapUpdateResult::Fail();
- }
- } else {
- get_class_info_function = m_get_class_info_code->GetFunctionCaller();
- if (!get_class_info_function) {
- LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
- return DescriptorMapUpdateResult::Fail();
- }
- arguments = get_class_info_function->GetArgumentValues();
+ if (!get_class_info_function) {
+ LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
+ return DescriptorMapUpdateResult::Fail();
}
+ ValueList arguments = get_class_info_function->GetArgumentValues();
+
DiagnosticManager diagnostics;
const uint32_t class_info_byte_size = addr_size + 4;
@@ -1390,18 +1804,18 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
return DescriptorMapUpdateResult::Fail();
}
- std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// Fill in our function argument values
arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
-
+
// Only dump the runtime classes from the expression evaluation if the log is
// verbose:
Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES);
bool dump_log = type_log && type_log->GetVerbose();
-
+
arguments.GetValueAtIndex(3)->GetScalar() = dump_log ? 1 : 0;
bool success = false;
@@ -1410,7 +1824,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
// Write our function arguments into the process so we can run our function
if (get_class_info_function->WriteFunctionArguments(
- exe_ctx, m_get_class_info_args, arguments, diagnostics)) {
+ exe_ctx, GetClassInfoArgs(helper), arguments, diagnostics)) {
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
options.SetTryAllThreads(false);
@@ -1419,8 +1833,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
options.SetTimeout(process->GetUtilityExpressionTimeout());
options.SetIsForUtilityExpr(true);
+ CompilerType clang_uint32_t_type =
+ ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+
Value return_value;
- return_value.SetValueType(Value::eValueTypeScalar);
+ return_value.SetValueType(Value::ValueType::Scalar);
return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
@@ -1428,12 +1845,12 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
// Run the function
ExpressionResults results = get_class_info_function->ExecuteFunction(
- exe_ctx, &m_get_class_info_args, options, diagnostics, return_value);
+ exe_ctx, &GetClassInfoArgs(helper), options, diagnostics, return_value);
if (results == eExpressionCompleted) {
// The result is the number of ClassInfo structures that were filled in
num_class_infos = return_value.GetScalar().ULong();
- LLDB_LOGF(log, "Discovered %u ObjC classes\n", num_class_infos);
+ LLDB_LOG(log, "Discovered {0} Objective-C classes", num_class_infos);
if (num_class_infos > 0) {
// Read the ClassInfo structures
DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
@@ -1443,7 +1860,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
DataExtractor class_infos_data(buffer.GetBytes(),
buffer.GetByteSize(),
process->GetByteOrder(), addr_size);
- ParseClassInfoArray(class_infos_data, num_class_infos);
+ m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
}
}
success = true;
@@ -1507,15 +1924,16 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
ClassDescriptorSP descriptor_sp(
new ClassDescriptorV2(*this, isa, nullptr));
- // The code in g_get_shared_cache_class_info_body sets the value of the hash
- // to 0 to signal a demangled symbol. We use class_getName() in that code to
- // find the class name, but this returns a demangled name for Swift symbols.
- // For those symbols, recompute the hash here by reading their name from the
- // runtime.
+ // The code in g_get_shared_cache_class_info_body sets the value of the
+ // hash to 0 to signal a demangled symbol. We use class_getName() in that
+ // code to find the class name, but this returns a demangled name for
+ // Swift symbols. For those symbols, recompute the hash here by reading
+ // their name from the runtime.
if (name_hash)
AddClass(isa, descriptor_sp, name_hash);
else
- AddClass(isa, descriptor_sp, descriptor_sp->GetClassName().AsCString(nullptr));
+ AddClass(isa, descriptor_sp,
+ descriptor_sp->GetClassName().AsCString(nullptr));
num_parsed++;
if (should_log)
LLDB_LOGF(log,
@@ -1531,10 +1949,20 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
return num_parsed;
}
-AppleObjCRuntimeV2::DescriptorMapUpdateResult
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
- Process *process = GetProcess();
+bool AppleObjCRuntimeV2::HasSymbol(ConstString Name) {
+ if (!m_objc_module_sp)
+ return false;
+ if (const Symbol *symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType(
+ Name, lldb::eSymbolTypeCode)) {
+ if (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())
+ return true;
+ }
+ return false;
+}
+AppleObjCRuntimeV2::DescriptorMapUpdateResult
+AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() {
+ Process *process = m_runtime.GetProcess();
if (process == nullptr)
return DescriptorMapUpdateResult::Fail();
@@ -1562,103 +1990,38 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
uint32_t num_class_infos = 0;
- const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
+ const lldb::addr_t objc_opt_ptr = m_runtime.GetSharedCacheReadOnlyAddress();
+ const lldb::addr_t shared_cache_base_addr =
+ m_runtime.GetSharedCacheBaseAddress();
- if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
+ if (objc_opt_ptr == LLDB_INVALID_ADDRESS ||
+ shared_cache_base_addr == LLDB_INVALID_ADDRESS)
return DescriptorMapUpdateResult::Fail();
const uint32_t num_classes = 128 * 1024;
- // Make some types for our arguments
- CompilerType clang_uint32_t_type =
- ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
- CompilerType clang_void_pointer_type =
- ast->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- ValueList arguments;
- FunctionCaller *get_shared_cache_class_info_function = nullptr;
-
- if (!m_get_shared_cache_class_info_code) {
- Status error;
-
- // If the inferior objc.dylib has the class_getNameRaw function,
- // use that in our jitted expression. Else fall back to the old
- // class_getName.
- static ConstString g_class_getName_symbol_name("class_getName");
- static ConstString g_class_getNameRaw_symbol_name("objc_debug_class_getNameRaw");
- ConstString class_name_getter_function_name = g_class_getName_symbol_name;
-
- ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
- if (objc_runtime) {
- for (lldb::ModuleSP mod_sp : process->GetTarget().GetImages().Modules()) {
- if (objc_runtime->IsModuleObjCLibrary(mod_sp)) {
- const Symbol *symbol =
- mod_sp->FindFirstSymbolWithNameAndType(g_class_getNameRaw_symbol_name,
- lldb::eSymbolTypeCode);
- if (symbol &&
- (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
- class_name_getter_function_name = g_class_getNameRaw_symbol_name;
- }
- }
- }
- }
-
- // Substitute in the correct class_getName / class_getNameRaw function name,
- // concatenate the two parts of our expression text. The format string
- // has two %s's, so provide the name twice.
- std::string shared_class_expression;
- llvm::raw_string_ostream(shared_class_expression) << llvm::format(
- g_shared_cache_class_name_funcptr,
- class_name_getter_function_name.AsCString(),
- class_name_getter_function_name.AsCString());
-
- shared_class_expression += g_get_shared_cache_class_info_body;
-
- auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
- std::move(shared_class_expression), g_get_shared_cache_class_info_name,
- eLanguageTypeC, exe_ctx);
- if (!utility_fn_or_error) {
- LLDB_LOG_ERROR(
- log, utility_fn_or_error.takeError(),
- "Failed to get utility function for implementation lookup: {0}");
- return DescriptorMapUpdateResult::Fail();
- }
-
- m_get_shared_cache_class_info_code = std::move(*utility_fn_or_error);
+ UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx);
+ FunctionCaller *get_shared_cache_class_info_function =
+ get_class_info_code->GetFunctionCaller();
- // Next make the function caller for our implementation utility function.
- Value value;
- value.SetValueType(Value::eValueTypeScalar);
- value.SetCompilerType(clang_void_pointer_type);
- arguments.PushValue(value);
- arguments.PushValue(value);
-
- value.SetValueType(Value::eValueTypeScalar);
- value.SetCompilerType(clang_uint32_t_type);
- arguments.PushValue(value);
- arguments.PushValue(value);
-
- get_shared_cache_class_info_function =
- m_get_shared_cache_class_info_code->MakeFunctionCaller(
- clang_uint32_t_type, arguments, thread_sp, error);
-
- if (get_shared_cache_class_info_function == nullptr)
- return DescriptorMapUpdateResult::Fail();
-
- } else {
- get_shared_cache_class_info_function =
- m_get_shared_cache_class_info_code->GetFunctionCaller();
- if (get_shared_cache_class_info_function == nullptr)
- return DescriptorMapUpdateResult::Fail();
- arguments = get_shared_cache_class_info_function->GetArgumentValues();
+ if (!get_shared_cache_class_info_function) {
+ LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
+ return DescriptorMapUpdateResult::Fail();
}
+ ValueList arguments =
+ get_shared_cache_class_info_function->GetArgumentValues();
+
DiagnosticManager diagnostics;
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
lldb::addr_t class_infos_addr = process->AllocateMemory(
class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
+ const uint32_t relative_selector_offset_addr_size = 64;
+ lldb::addr_t relative_selector_offset_addr =
+ process->AllocateMemory(relative_selector_offset_addr_size,
+ ePermissionsReadable | ePermissionsWritable, err);
if (class_infos_addr == LLDB_INVALID_ADDRESS) {
LLDB_LOGF(log,
@@ -1668,18 +2031,20 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
return DescriptorMapUpdateResult::Fail();
}
- std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// Fill in our function argument values
arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
- arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
- arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+ arguments.GetValueAtIndex(1)->GetScalar() = shared_cache_base_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = class_infos_addr;
+ arguments.GetValueAtIndex(3)->GetScalar() = relative_selector_offset_addr;
+ arguments.GetValueAtIndex(4)->GetScalar() = class_infos_byte_size;
// Only dump the runtime classes from the expression evaluation if the log is
// verbose:
Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES);
bool dump_log = type_log && type_log->GetVerbose();
-
- arguments.GetValueAtIndex(3)->GetScalar() = dump_log ? 1 : 0;
+
+ arguments.GetValueAtIndex(5)->GetScalar() = dump_log ? 1 : 0;
bool success = false;
@@ -1687,8 +2052,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
// Write our function arguments into the process so we can run our function
if (get_shared_cache_class_info_function->WriteFunctionArguments(
- exe_ctx, m_get_shared_cache_class_info_args, arguments,
- diagnostics)) {
+ exe_ctx, m_args, arguments, diagnostics)) {
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
options.SetTryAllThreads(false);
@@ -1697,8 +2061,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
options.SetTimeout(process->GetUtilityExpressionTimeout());
options.SetIsForUtilityExpr(true);
+ CompilerType clang_uint32_t_type =
+ ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+
Value return_value;
- return_value.SetValueType(Value::eValueTypeScalar);
+ return_value.SetValueType(Value::ValueType::Scalar);
return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
@@ -1707,14 +2074,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
// Run the function
ExpressionResults results =
get_shared_cache_class_info_function->ExecuteFunction(
- exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics,
- return_value);
+ exe_ctx, &m_args, options, diagnostics, return_value);
if (results == eExpressionCompleted) {
// The result is the number of ClassInfo structures that were filled in
num_class_infos = return_value.GetScalar().ULong();
- LLDB_LOGF(log, "Discovered %u ObjC classes in shared cache\n",
- num_class_infos);
+ LLDB_LOG(log, "Discovered {0} Objective-C classes in the shared cache",
+ num_class_infos);
assert(num_class_infos <= num_classes);
if (num_class_infos > 0) {
if (num_class_infos > num_classes) {
@@ -1725,16 +2091,38 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
success = true;
}
+ // Read the relative selector offset.
+ DataBufferHeap relative_selector_offset_buffer(64, 0);
+ if (process->ReadMemory(relative_selector_offset_addr,
+ relative_selector_offset_buffer.GetBytes(),
+ relative_selector_offset_buffer.GetByteSize(),
+ err) ==
+ relative_selector_offset_buffer.GetByteSize()) {
+ DataExtractor relative_selector_offset_data(
+ relative_selector_offset_buffer.GetBytes(),
+ relative_selector_offset_buffer.GetByteSize(),
+ process->GetByteOrder(), addr_size);
+ lldb::offset_t offset = 0;
+ uint64_t relative_selector_offset =
+ relative_selector_offset_data.GetU64(&offset);
+ if (relative_selector_offset > 0) {
+ // The offset is relative to the objc_opt struct.
+ m_runtime.SetRelativeSelectorBaseAddr(objc_opt_ptr +
+ relative_selector_offset);
+ }
+ }
+
// Read the ClassInfo structures
- DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
- if (process->ReadMemory(class_infos_addr, buffer.GetBytes(),
- buffer.GetByteSize(),
- err) == buffer.GetByteSize()) {
- DataExtractor class_infos_data(buffer.GetBytes(),
- buffer.GetByteSize(),
+ DataBufferHeap class_infos_buffer(
+ num_class_infos * class_info_byte_size, 0);
+ if (process->ReadMemory(class_infos_addr, class_infos_buffer.GetBytes(),
+ class_infos_buffer.GetByteSize(),
+ err) == class_infos_buffer.GetByteSize()) {
+ DataExtractor class_infos_data(class_infos_buffer.GetBytes(),
+ class_infos_buffer.GetByteSize(),
process->GetByteOrder(), addr_size);
- ParseClassInfoArray(class_infos_data, num_class_infos);
+ m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
}
} else {
success = true;
@@ -1758,42 +2146,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
return DescriptorMapUpdateResult(success, num_class_infos);
}
-bool AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory(
- RemoteNXMapTable &hash_table) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
-
- Process *process = GetProcess();
-
- if (process == nullptr)
- return false;
-
- uint32_t num_map_table_isas = 0;
-
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (objc_module_sp) {
- for (RemoteNXMapTable::element elt : hash_table) {
- ++num_map_table_isas;
-
- if (ISAIsCached(elt.second))
- continue;
-
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(
- new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
-
- if (log && log->GetVerbose())
- LLDB_LOGF(log,
- "AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64
- " (%s) from dynamic table to isa->descriptor cache",
- elt.second, elt.first.AsCString());
-
- AddClass(elt.second, descriptor_sp, elt.first.AsCString());
- }
- }
-
- return num_map_table_isas > 0;
-}
-
lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress() {
Process *process = GetProcess();
@@ -1827,6 +2179,19 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress() {
return LLDB_INVALID_ADDRESS;
}
+lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() {
+ StructuredData::ObjectSP info = m_process->GetSharedCacheInfo();
+ if (!info)
+ return LLDB_INVALID_ADDRESS;
+
+ StructuredData::Dictionary *info_dict = info->GetAsDictionary();
+ if (!info_dict)
+ return LLDB_INVALID_ADDRESS;
+
+ return info_dict->GetValueForKey("shared_cache_base_address")
+ ->GetIntegerValue(LLDB_INVALID_ADDRESS);
+}
+
void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
LLDB_SCOPED_TIMER();
@@ -1842,14 +2207,19 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
// map, whether it was successful or not.
m_isa_to_descriptor_stop_id = process->GetStopID();
- if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
+ // Ask the runtime is the realized class generation count changed. Unlike
+ // the hash table, this accounts for lazily named classes.
+ const bool class_count_changed = RealizedClassGenerationCountChanged();
+
+ if (!m_hash_signature.NeedsUpdate(process, this, hash_table) &&
+ !class_count_changed)
return;
m_hash_signature.UpdateSignature(hash_table);
- // Grab the dynamically loaded objc classes from the hash table in memory
+ // Grab the dynamically loaded Objective-C classes from memory.
DescriptorMapUpdateResult dynamic_update_result =
- UpdateISAToDescriptorMapDynamic(hash_table);
+ m_dynamic_class_info_extractor.UpdateISAToDescriptorMap(hash_table);
// Now get the objc classes that are baked into the Objective-C runtime in
// the shared cache, but only once per process as this data never changes
@@ -1865,7 +2235,7 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
const uint32_t num_classes_to_warn_at = 500;
DescriptorMapUpdateResult shared_cache_update_result =
- UpdateISAToDescriptorMapSharedCache();
+ m_shared_cache_class_info_extractor.UpdateISAToDescriptorMap();
LLDB_LOGF(log,
"attempted to read objc class data - results: "
@@ -1895,6 +2265,35 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
}
}
+bool AppleObjCRuntimeV2::RealizedClassGenerationCountChanged() {
+ Process *process = GetProcess();
+ if (!process)
+ return false;
+
+ Status error;
+ uint64_t objc_debug_realized_class_generation_count =
+ ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_realized_class_generation_count"),
+ GetObjCModule(), error);
+ if (error.Fail())
+ return false;
+
+ if (m_realized_class_generation_count ==
+ objc_debug_realized_class_generation_count)
+ return false;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+ LLDB_LOG(log,
+ "objc_debug_realized_class_generation_count changed from {0} to {1}",
+ m_realized_class_generation_count,
+ objc_debug_realized_class_generation_count);
+
+ m_realized_class_generation_count =
+ objc_debug_realized_class_generation_count;
+
+ return true;
+}
+
static bool DoesProcessHaveSharedCache(Process &process) {
PlatformSP platform_sp = process.GetTarget().GetPlatform();
if (!platform_sp)
@@ -1975,9 +2374,10 @@ lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(ConstString name) {
const ConstString ivar_name_cs(class_and_ivar.second);
const char *ivar_name_cstr = ivar_name_cs.AsCString();
- auto ivar_func = [&ret, ivar_name_cstr](
- const char *name, const char *type, lldb::addr_t offset_addr,
- uint64_t size) -> lldb::addr_t {
+ auto ivar_func = [&ret,
+ ivar_name_cstr](const char *name, const char *type,
+ lldb::addr_t offset_addr,
+ uint64_t size) -> lldb::addr_t {
if (!strcmp(name, ivar_name_cstr)) {
ret = offset_addr;
return true;
@@ -2279,7 +2679,6 @@ ObjCLanguageRuntime::ClassDescriptorSP
AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
lldb::addr_t ptr) {
ClassDescriptorSP actual_class_descriptor_sp;
- uint64_t data_payload;
uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
if (!IsPossibleTaggedPointer(unobfuscated))
@@ -2307,12 +2706,15 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
m_cache[slot] = actual_class_descriptor_sp;
}
- data_payload =
+ uint64_t data_payload =
(((uint64_t)unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
m_objc_debug_taggedpointer_payload_rshift);
-
- return ClassDescriptorSP(
- new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
+ int64_t data_payload_signed =
+ ((int64_t)((int64_t)unobfuscated
+ << m_objc_debug_taggedpointer_payload_lshift) >>
+ m_objc_debug_taggedpointer_payload_rshift);
+ return ClassDescriptorSP(new ClassDescriptorV2Tagged(
+ actual_class_descriptor_sp, data_payload, data_payload_signed));
}
AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended(
@@ -2364,7 +2766,6 @@ ObjCLanguageRuntime::ClassDescriptorSP
AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
lldb::addr_t ptr) {
ClassDescriptorSP actual_class_descriptor_sp;
- uint64_t data_payload;
uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
if (!IsPossibleTaggedPointer(unobfuscated))
@@ -2395,12 +2796,16 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
m_ext_cache[slot] = actual_class_descriptor_sp;
}
- data_payload =
- (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >>
+ uint64_t data_payload = (((uint64_t)unobfuscated
+ << m_objc_debug_taggedpointer_ext_payload_lshift) >>
+ m_objc_debug_taggedpointer_ext_payload_rshift);
+ int64_t data_payload_signed =
+ ((int64_t)((int64_t)unobfuscated
+ << m_objc_debug_taggedpointer_ext_payload_lshift) >>
m_objc_debug_taggedpointer_ext_payload_rshift);
- return ClassDescriptorSP(
- new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
+ return ClassDescriptorSP(new ClassDescriptorV2Tagged(
+ actual_class_descriptor_sp, data_payload, data_payload_signed));
}
AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache(
@@ -2552,8 +2957,8 @@ lldb_private::AppleObjCRuntime::ObjCISA
AppleObjCRuntimeV2::GetPointerISA(ObjCISA isa) {
ObjCISA ret = isa;
- if (m_non_pointer_isa_cache_up)
- m_non_pointer_isa_cache_up->EvaluateNonPointerISA(isa, ret);
+ if (auto *non_pointer_isa_cache = GetNonPointerIsaCache())
+ non_pointer_isa_cache->EvaluateNonPointerISA(isa, ret);
return ret;
}
@@ -2598,13 +3003,14 @@ void AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
#pragma mark Frame recognizers
class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
- public:
+public:
ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp) {
ThreadSP thread_sp = frame_sp->GetThread();
ProcessSP process_sp = thread_sp->GetProcess();
const lldb::ABISP &abi = process_sp->GetABI();
- if (!abi) return;
+ if (!abi)
+ return;
TypeSystemClang *clang_ast_context =
ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
@@ -2618,7 +3024,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
input_value.SetCompilerType(voidstar);
args.PushValue(input_value);
- if (!abi->GetArgumentValues(*thread_sp, args)) return;
+ if (!abi->GetArgumentValues(*thread_sp, args))
+ return;
addr_t exception_addr = args.GetValueAtIndex(0)->GetScalar().ULongLong();
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index c6fb6ea26b98..d0caa2969115 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -26,7 +26,6 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {
public:
~AppleObjCRuntimeV2() override = default;
- // Static Functions
static void Initialize();
static void Terminate();
@@ -46,7 +45,6 @@ public:
return runtime->isA(&ID);
}
- // These are generic runtime functions:
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
@@ -56,7 +54,6 @@ public:
llvm::Expected<std::unique_ptr<UtilityFunction>>
CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override;
- // PluginInterface protocol
ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
@@ -88,6 +85,15 @@ public:
lldb::addr_t GetTaggedPointerObfuscator();
+ /// Returns the base address for relative method list selector strings.
+ lldb::addr_t GetRelativeSelectorBaseAddr() {
+ return m_relative_selector_base;
+ }
+
+ void SetRelativeSelectorBaseAddr(lldb::addr_t relative_selector_base) {
+ m_relative_selector_base = relative_selector_base;
+ }
+
void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
lldb::addr_t &cf_false) override;
@@ -105,8 +111,8 @@ public:
protected:
lldb::BreakpointResolverSP
- CreateExceptionResolver(const lldb::BreakpointSP &bkpt,
- bool catch_bp, bool throw_bp) override;
+ CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
+ bool throw_bp) override;
private:
class HashTableSignature {
@@ -119,9 +125,9 @@ private:
void UpdateSignature(const RemoteNXMapTable &hash_table);
protected:
- uint32_t m_count;
- uint32_t m_num_buckets;
- lldb::addr_t m_buckets_ptr;
+ uint32_t m_count = 0;
+ uint32_t m_num_buckets = 0;
+ lldb::addr_t m_buckets_ptr = 0;
};
class NonPointerISACache {
@@ -296,22 +302,99 @@ private:
}
};
+ /// Abstraction to read the Objective-C class info.
+ class ClassInfoExtractor {
+ public:
+ ClassInfoExtractor(AppleObjCRuntimeV2 &runtime) : m_runtime(runtime) {}
+ std::mutex &GetMutex() { return m_mutex; }
+
+ protected:
+ /// The lifetime of this object is tied to that of the runtime.
+ AppleObjCRuntimeV2 &m_runtime;
+ std::mutex m_mutex;
+ };
+
+ /// We can read the class info from the Objective-C runtime using
+ /// gdb_objc_realized_classes or objc_copyRealizedClassList. The latter is
+ /// preferred because it includes lazily named classes, but it's not always
+ /// available or safe to call.
+ ///
+ /// We potentially need both for the same process, because we may need to use
+ /// gdb_objc_realized_classes until dyld is initialized and then switch over
+ /// to objc_copyRealizedClassList for lazily named classes.
+ class DynamicClassInfoExtractor : public ClassInfoExtractor {
+ public:
+ DynamicClassInfoExtractor(AppleObjCRuntimeV2 &runtime)
+ : ClassInfoExtractor(runtime) {}
+
+ DescriptorMapUpdateResult
+ UpdateISAToDescriptorMap(RemoteNXMapTable &hash_table);
+
+ private:
+ enum Helper { gdb_objc_realized_classes, objc_copyRealizedClassList };
+
+ /// Compute which helper to use. Prefer objc_copyRealizedClassList if it's
+ /// available and it's safe to call (i.e. dyld is fully initialized). Use
+ /// gdb_objc_realized_classes otherwise.
+ Helper ComputeHelper() const;
+
+ UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx,
+ Helper helper);
+ lldb::addr_t &GetClassInfoArgs(Helper helper);
+
+ std::unique_ptr<UtilityFunction>
+ GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx, std::string code,
+ std::string name);
+
+ /// Helper to read class info using the gdb_objc_realized_classes.
+ struct gdb_objc_realized_classes_helper {
+ std::unique_ptr<UtilityFunction> utility_function;
+ lldb::addr_t args = LLDB_INVALID_ADDRESS;
+ };
+
+ /// Helper to read class info using objc_copyRealizedClassList.
+ struct objc_copyRealizedClassList_helper {
+ std::unique_ptr<UtilityFunction> utility_function;
+ lldb::addr_t args = LLDB_INVALID_ADDRESS;
+ };
+
+ gdb_objc_realized_classes_helper m_gdb_objc_realized_classes_helper;
+ objc_copyRealizedClassList_helper m_objc_copyRealizedClassList_helper;
+ };
+
+ /// Abstraction to read the Objective-C class info from the shared cache.
+ class SharedCacheClassInfoExtractor : public ClassInfoExtractor {
+ public:
+ SharedCacheClassInfoExtractor(AppleObjCRuntimeV2 &runtime)
+ : ClassInfoExtractor(runtime) {}
+
+ DescriptorMapUpdateResult UpdateISAToDescriptorMap();
+
+ private:
+ UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx);
+
+ std::unique_ptr<UtilityFunction>
+ GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx);
+
+ std::unique_ptr<UtilityFunction> m_utility_function;
+ lldb::addr_t m_args = LLDB_INVALID_ADDRESS;
+ };
+
AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
ObjCISA GetPointerISA(ObjCISA isa);
lldb::addr_t GetISAHashTablePointer();
- bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
-
- DescriptorMapUpdateResult
- UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
+ /// Update the generation count of realized classes. This is not an exact
+ /// count but rather a value that is incremented when new classes are realized
+ /// or destroyed. Unlike the count in gdb_objc_realized_classes, it will
+ /// change when lazily named classes get realized.
+ bool RealizedClassGenerationCountChanged();
uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
uint32_t num_class_infos);
- DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
-
enum class SharedCacheWarningReason {
eExpressionExecutionFailure,
eNotEnoughClassesRead
@@ -320,30 +403,40 @@ private:
void WarnIfNoClassesCached(SharedCacheWarningReason reason);
lldb::addr_t GetSharedCacheReadOnlyAddress();
+ lldb::addr_t GetSharedCacheBaseAddress();
bool GetCFBooleanValuesIfNeeded();
+ bool HasSymbol(ConstString Name);
+
+ NonPointerISACache *GetNonPointerIsaCache() {
+ if (!m_non_pointer_isa_cache_up)
+ m_non_pointer_isa_cache_up.reset(
+ NonPointerISACache::CreateInstance(*this, m_objc_module_sp));
+ return m_non_pointer_isa_cache_up.get();
+ }
+
friend class ClassDescriptorV2;
- std::unique_ptr<UtilityFunction> m_get_class_info_code;
- lldb::addr_t m_get_class_info_args;
- std::mutex m_get_class_info_args_mutex;
+ lldb::ModuleSP m_objc_module_sp;
- std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
- lldb::addr_t m_get_shared_cache_class_info_args;
- std::mutex m_get_shared_cache_class_info_args_mutex;
+ DynamicClassInfoExtractor m_dynamic_class_info_extractor;
+ SharedCacheClassInfoExtractor m_shared_cache_class_info_extractor;
std::unique_ptr<DeclVendor> m_decl_vendor_up;
lldb::addr_t m_tagged_pointer_obfuscator;
lldb::addr_t m_isa_hash_table_ptr;
+ lldb::addr_t m_relative_selector_base;
HashTableSignature m_hash_signature;
bool m_has_object_getClass;
+ bool m_has_objc_copyRealizedClassList;
bool m_loaded_objc_opt;
std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up;
std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up;
EncodingToTypeSP m_encoding_to_type_sp;
bool m_noclasses_warning_emitted;
llvm::Optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
+ uint64_t m_realized_class_generation_count;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index bcc1f6fd339f..aa6306bef8b9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -285,7 +285,7 @@ AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(
SetUpRegion();
}
-AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() {}
+AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() = default;
void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() {
// The header looks like:
@@ -526,7 +526,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- input_value.SetValueType(Value::eValueTypeScalar);
+ input_value.SetValueType(Value::ValueType::Scalar);
// input_value.SetContext (Value::eContextTypeClangType,
// clang_void_ptr_type);
input_value.SetCompilerType(clang_void_ptr_type);
@@ -936,7 +936,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
Value void_ptr_value;
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- void_ptr_value.SetValueType(Value::eValueTypeScalar);
+ void_ptr_value.SetValueType(Value::ValueType::Scalar);
// void_ptr_value.SetContext (Value::eContextTypeClangType,
// clang_void_ptr_type);
void_ptr_value.SetCompilerType(clang_void_ptr_type);
@@ -1048,7 +1048,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
- isa_value.SetValueType(Value::eValueTypeLoadAddress);
+ isa_value.SetValueType(Value::ValueType::LoadAddress);
isa_value.ResolveValue(&exe_ctx);
if (isa_value.GetScalar().IsValid()) {
isa_addr = isa_value.GetScalar().ULongLong();
@@ -1110,7 +1110,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
CompilerType clang_int_type =
clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
lldb::eEncodingSint, 32);
- flag_value.SetValueType(Value::eValueTypeScalar);
+ flag_value.SetValueType(Value::ValueType::Scalar);
// flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
flag_value.SetCompilerType(clang_int_type);
@@ -1157,13 +1157,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done.
dispatch_values.PushValue(flag_value);
- // The step through code might have to fill in the cache, so it
- // is not safe to run only one thread. So we override the
- // stop_others value passed in to us here:
- const bool trampoline_stop_others = false;
ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughObjCTrampoline>(
- thread, *this, dispatch_values, isa_addr, sel_addr,
- trampoline_stop_others);
+ thread, *this, dispatch_values, isa_addr, sel_addr);
if (log) {
StreamString s;
ret_plan_sp->GetDescription(&s, eDescriptionLevelFull);
@@ -1182,13 +1177,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
MsgsendMap::iterator pos;
pos = m_opt_dispatch_map.find(curr_pc);
if (pos != m_opt_dispatch_map.end()) {
-
const char *opt_name = g_opt_dispatch_names[(*pos).second];
-
- bool trampoline_stop_others = false;
- LazyBool step_in_should_stop = eLazyBoolCalculate;
- ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch> (
- thread, *this, opt_name, trampoline_stop_others, step_in_should_stop);
+ ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch>(
+ thread, *this, opt_name);
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index 27aebd8594df..546b500b4529 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -76,10 +76,7 @@ private:
class VTableRegion {
public:
- VTableRegion()
- : m_valid(false), m_owner(nullptr),
- m_header_addr(LLDB_INVALID_ADDRESS), m_code_start_addr(0),
- m_code_end_addr(0), m_next_region(0) {}
+ VTableRegion() = default;
VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
@@ -99,13 +96,13 @@ private:
void Dump(Stream &s);
- bool m_valid;
- AppleObjCVTables *m_owner;
- lldb::addr_t m_header_addr;
- lldb::addr_t m_code_start_addr;
- lldb::addr_t m_code_end_addr;
+ bool m_valid = false;
+ AppleObjCVTables *m_owner = nullptr;
+ lldb::addr_t m_header_addr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t m_code_start_addr = 0;
+ lldb::addr_t m_code_end_addr = 0;
std::vector<VTableDescriptor> m_descriptors;
- lldb::addr_t m_next_region;
+ lldb::addr_t m_next_region = 0;
};
public:
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index b19d3d90d4b7..7b0121503bc4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -59,7 +59,7 @@ uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) {
// "{CGRect=\"origin\"{CGPoint=\"x\"d\"y\"d}\"size\"{CGSize=\"width\"d\"height\"d}}"
AppleObjCTypeEncodingParser::StructElement::StructElement()
- : name(""), type(clang::QualType()), bitfield(0) {}
+ : name(""), type(clang::QualType()) {}
AppleObjCTypeEncodingParser::StructElement
AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index 9a108967e1ab..6e533b591eca 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -29,7 +29,7 @@ private:
struct StructElement {
std::string name;
clang::QualType type;
- uint32_t bitfield;
+ uint32_t bitfield = 0;
StructElement();
~StructElement() = default;
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index 653e007c7b5f..1dc8034c537a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -30,19 +30,17 @@ using namespace lldb_private;
AppleThreadPlanStepThroughObjCTrampoline::
AppleThreadPlanStepThroughObjCTrampoline(
Thread &thread, AppleObjCTrampolineHandler &trampoline_handler,
- ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
- bool stop_others)
+ ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr)
: ThreadPlan(ThreadPlan::eKindGeneric,
"MacOSX Step through ObjC Trampoline", thread, eVoteNoOpinion,
eVoteNoOpinion),
m_trampoline_handler(trampoline_handler),
m_args_addr(LLDB_INVALID_ADDRESS), m_input_values(input_values),
- m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(nullptr),
- m_stop_others(stop_others) {}
+ m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(nullptr) {}
// Destructor
AppleThreadPlanStepThroughObjCTrampoline::
- ~AppleThreadPlanStepThroughObjCTrampoline() {}
+ ~AppleThreadPlanStepThroughObjCTrampoline() = default;
void AppleThreadPlanStepThroughObjCTrampoline::DidPush() {
// Setting up the memory space for the called function text might require
@@ -66,7 +64,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() {
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
options.SetIgnoreBreakpoints(true);
- options.SetStopOthers(m_stop_others);
+ options.SetStopOthers(false);
GetThread().CalculateExecutionContext(exc_ctx);
m_func_sp = m_impl_function->GetThreadPlanToCallFunction(
exc_ctx, m_args_addr, options, diagnostics);
@@ -157,7 +155,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
const bool first_insn = true;
const uint32_t frame_idx = 0;
m_run_to_sp = GetThread().QueueThreadPlanForStepOutNoShouldStop(
- abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion,
+ abort_other_plans, &sc, first_insn, false, eVoteNoOpinion,
eVoteNoOpinion, frame_idx, status);
if (m_run_to_sp && status.Success())
m_run_to_sp->SetPrivate(true);
@@ -179,7 +177,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
// Extract the target address from the value:
m_run_to_sp = std::make_shared<ThreadPlanRunToAddress>(
- GetThread(), target_so_addr, m_stop_others);
+ GetThread(), target_so_addr, false);
PushPlan(m_run_to_sp);
return false;
} else if (GetThread().IsThreadPlanDone(m_run_to_sp.get())) {
@@ -222,10 +220,9 @@ bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; }
AppleThreadPlanStepThroughDirectDispatch ::
AppleThreadPlanStepThroughDirectDispatch(
Thread &thread, AppleObjCTrampolineHandler &handler,
- llvm::StringRef dispatch_func_name, bool stop_others,
- LazyBool step_in_avoids_code_without_debug_info)
- : ThreadPlanStepOut(thread, nullptr, true /* first instruction */,
- stop_others, eVoteNoOpinion, eVoteNoOpinion,
+ llvm::StringRef dispatch_func_name)
+ : ThreadPlanStepOut(thread, nullptr, true /* first instruction */, false,
+ eVoteNoOpinion, eVoteNoOpinion,
0 /* Step out of zeroth frame */,
eLazyBoolNo /* Our parent plan will decide this
when we are done */
@@ -234,7 +231,7 @@ AppleThreadPlanStepThroughDirectDispatch ::
false /* Don't gather the return value */),
m_trampoline_handler(handler),
m_dispatch_func_name(std::string(dispatch_func_name)),
- m_at_msg_send(false), m_stop_others(stop_others) {
+ m_at_msg_send(false) {
// Set breakpoints on the dispatch functions:
auto bkpt_callback = [&] (lldb::addr_t addr,
const AppleObjCTrampolineHandler
@@ -249,20 +246,7 @@ AppleThreadPlanStepThroughDirectDispatch ::
// We'll set the step-out plan in the DidPush so it gets queued in the right
// order.
- bool avoid_nodebug = true;
-
- switch (step_in_avoids_code_without_debug_info) {
- case eLazyBoolYes:
- avoid_nodebug = true;
- break;
- case eLazyBoolNo:
- avoid_nodebug = false;
- break;
- case eLazyBoolCalculate:
- avoid_nodebug = GetThread().GetStepInAvoidsNoDebug();
- break;
- }
- if (avoid_nodebug)
+ if (GetThread().GetStepInAvoidsNoDebug())
GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
else
GetFlags().Clear(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
@@ -398,8 +382,8 @@ bool AppleThreadPlanStepThroughDirectDispatch::ShouldStop(Event *event_ptr) {
// There's no way we could have gotten here without an ObjC language
// runtime.
assert(objc_runtime);
- m_objc_step_through_sp
- = objc_runtime->GetStepThroughTrampolinePlan(GetThread(), m_stop_others);
+ m_objc_step_through_sp =
+ objc_runtime->GetStepThroughTrampolinePlan(GetThread(), false);
// If we failed to find the target for this dispatch, just keep going and
// let the step out complete.
if (!m_objc_step_through_sp) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
index 89aed89f1ab1..b5b45079094c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
@@ -24,8 +24,7 @@ class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan {
public:
AppleThreadPlanStepThroughObjCTrampoline(
Thread &thread, AppleObjCTrampolineHandler &trampoline_handler,
- ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
- bool stop_others);
+ ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr);
~AppleThreadPlanStepThroughObjCTrampoline() override;
@@ -39,7 +38,9 @@ public:
bool ShouldStop(Event *event_ptr) override;
- bool StopOthers() override { return m_stop_others; }
+ // The step through code might have to fill in the cache, so it is not safe
+ // to run only one thread.
+ bool StopOthers() override { return false; }
// The base class MischiefManaged does some cleanup - so you have to call it
// in your MischiefManaged derived class.
@@ -69,15 +70,13 @@ private:
FunctionCaller *m_impl_function; /// This is a pointer to a impl function that
/// is owned by the client that pushes this
/// plan.
- bool m_stop_others; /// Whether we should stop other threads.
};
class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut {
public:
- AppleThreadPlanStepThroughDirectDispatch(
- Thread &thread, AppleObjCTrampolineHandler &handler,
- llvm::StringRef dispatch_func_name, bool stop_others,
- LazyBool step_in_avoids_code_without_debug_info);
+ AppleThreadPlanStepThroughDirectDispatch(Thread &thread,
+ AppleObjCTrampolineHandler &handler,
+ llvm::StringRef dispatch_func_name);
~AppleThreadPlanStepThroughDirectDispatch() override;
@@ -85,7 +84,7 @@ public:
bool ShouldStop(Event *event_ptr) override;
- bool StopOthers() override { return m_stop_others; }
+ bool StopOthers() override { return false; }
bool MischiefManaged() override;
@@ -107,7 +106,6 @@ protected:
std::vector<lldb::BreakpointSP> m_msgSend_bkpts; /// Breakpoints on the objc
/// dispatch functions.
bool m_at_msg_send; /// Are we currently handling an msg_send
- bool m_stop_others; /// Whether we should stop other threads.
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index 2ccf9b33f9d8..65bf3e6af626 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -32,7 +32,7 @@ using namespace lldb_private;
char ObjCLanguageRuntime::ID = 0;
// Destructor
-ObjCLanguageRuntime::~ObjCLanguageRuntime() {}
+ObjCLanguageRuntime::~ObjCLanguageRuntime() = default;
ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process)
: LanguageRuntime(process), m_impl_cache(),
@@ -305,7 +305,7 @@ ObjCLanguageRuntime::EncodingToType::RealizeType(const char *name,
return CompilerType();
}
-ObjCLanguageRuntime::EncodingToType::~EncodingToType() {}
+ObjCLanguageRuntime::EncodingToType::~EncodingToType() = default;
ObjCLanguageRuntime::EncodingToTypeSP ObjCLanguageRuntime::GetEncodingToType() {
return nullptr;
@@ -363,7 +363,8 @@ void ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName(
m_class_names.insert(class_name);
}
-ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition() {}
+ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition() =
+ default;
bool ObjCLanguageRuntime::ObjCExceptionPrecondition::EvaluatePrecondition(
StoppointCallbackContext &context) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index 683eff777728..15fce04ea465 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -49,9 +49,7 @@ public:
// implementations of the runtime, and more might come
class ClassDescriptor {
public:
- ClassDescriptor()
- : m_is_kvo(eLazyBoolCalculate), m_is_cf(eLazyBoolCalculate),
- m_type_wp() {}
+ ClassDescriptor() : m_type_wp() {}
virtual ~ClassDescriptor() = default;
@@ -87,10 +85,20 @@ public:
virtual bool IsValid() = 0;
+ /// There are two routines in the ObjC runtime that tagged pointer clients
+ /// can call to get the value from their tagged pointer, one that retrieves
+ /// it as an unsigned value and one a signed value. These two
+ /// GetTaggedPointerInfo methods mirror those two ObjC runtime calls.
+ /// @{
virtual bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
uint64_t *value_bits = nullptr,
uint64_t *payload = nullptr) = 0;
+ virtual bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+ int64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) = 0;
+ /// @}
+
virtual uint64_t GetInstanceSize() = 0;
// use to implement version-specific additional constraints on pointers
@@ -135,8 +143,8 @@ public:
bool check_version_specific = false) const;
private:
- LazyBool m_is_kvo;
- LazyBool m_is_cf;
+ LazyBool m_is_kvo = eLazyBoolCalculate;
+ LazyBool m_is_cf = eLazyBoolCalculate;
lldb::TypeWP m_type_wp;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
index 6858c7134d33..08a752eaa888 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -185,7 +185,7 @@ RSIRPasses::RSIRPasses(Process *process) {
EarlyPasses->add(new RenderScriptRuntimeModulePass(process));
}
-RSIRPasses::~RSIRPasses() {}
+RSIRPasses::~RSIRPasses() = default;
} // namespace lldb_renderscript
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index dd9312234d8b..10ff5aa72b52 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -61,7 +61,7 @@ namespace {
template <typename type_t> class empirical_type {
public:
// Ctor. Contents is invalid when constructed.
- empirical_type() : valid(false) {}
+ empirical_type() = default;
// Return true and copy contents to out if valid, else return false.
bool get(type_t &out) const {
@@ -99,7 +99,7 @@ public:
}
protected:
- bool valid;
+ bool valid = false;
type_t data;
};
@@ -2228,7 +2228,7 @@ bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc,
return JITAllocationSize(alloc, frame_ptr);
}
-// Function attempts to set the type_name member of the paramaterised Element
+// Function attempts to set the type_name member of the parameterised Element
// object. This string should be the name of the struct type the Element
// represents. We need this string for pretty printing the Element to users.
void RenderScriptRuntime::FindStructTypeName(Element &elem,
@@ -4087,9 +4087,7 @@ public:
class CommandOptions : public Options {
public:
- CommandOptions()
- : Options(),
- m_kernel_types(RSReduceBreakpointResolver::eKernelTypeAll) {}
+ CommandOptions() : Options() {}
~CommandOptions() override = default;
@@ -4175,7 +4173,7 @@ public:
return true;
}
- int m_kernel_types;
+ int m_kernel_types = RSReduceBreakpointResolver::eKernelTypeAll;
llvm::StringRef m_reduce_name;
RSCoordinate m_coord;
bool m_have_coord;
@@ -4189,7 +4187,6 @@ public:
result.AppendErrorWithFormat("'%s' takes 1 argument of reduction name, "
"and an optional kernel type list",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4203,7 +4200,6 @@ public:
auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
if (!runtime->PlaceBreakpointOnReduction(target, outstream, name, coord,
m_options.m_kernel_types)) {
- result.SetStatus(eReturnStatusFailed);
result.AppendError("Error: unable to place breakpoint on reduction");
return false;
}
@@ -4291,7 +4287,6 @@ public:
result.AppendErrorWithFormat(
"'%s' takes 1 argument of kernel name, and an optional coordinate.",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4304,7 +4299,6 @@ public:
auto name = command.GetArgumentAtIndex(0);
auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
if (!runtime->PlaceBreakpointOnKernel(target, outstream, name, coord)) {
- result.SetStatus(eReturnStatusFailed);
result.AppendErrorWithFormat(
"Error: unable to set breakpoint on kernel '%s'", name);
return false;
@@ -4342,7 +4336,6 @@ public:
if (argc != 1) {
result.AppendErrorWithFormat(
"'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4361,7 +4354,6 @@ public:
} else {
result.AppendErrorWithFormat(
"Argument must be either 'enable' or 'disable'");
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4568,7 +4560,6 @@ public:
result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. "
"As well as an optional -f argument",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4583,7 +4574,6 @@ public:
if (!success) {
result.AppendErrorWithFormat("invalid allocation id argument '%s'",
id_cstr);
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4608,7 +4598,6 @@ public:
std::string error = llvm::toString(file.takeError());
result.AppendErrorWithFormat("Couldn't open file '%s': %s",
path.c_str(), error.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
} else
@@ -4653,7 +4642,7 @@ public:
class CommandOptions : public Options {
public:
- CommandOptions() : Options(), m_id(0) {}
+ CommandOptions() : Options() {}
~CommandOptions() override = default;
@@ -4681,7 +4670,7 @@ public:
return llvm::makeArrayRef(g_renderscript_runtime_alloc_list_options);
}
- uint32_t m_id;
+ uint32_t m_id = 0;
};
bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -4717,7 +4706,6 @@ public:
result.AppendErrorWithFormat(
"'%s' takes 2 arguments, an allocation ID and filename to read from.",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4732,7 +4720,6 @@ public:
if (!success) {
result.AppendErrorWithFormat("invalid allocation id argument '%s'",
id_cstr);
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4768,7 +4755,6 @@ public:
result.AppendErrorWithFormat(
"'%s' takes 2 arguments, an allocation ID and filename to read from.",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4783,7 +4769,6 @@ public:
if (!success) {
result.AppendErrorWithFormat("invalid allocation id argument '%s'",
id_cstr);
- result.SetStatus(eReturnStatusFailed);
return false;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 5e3726548369..2785c3b08125 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -44,9 +44,9 @@ typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP;
struct RSCoordinate {
- uint32_t x, y, z;
+ uint32_t x = 0, y = 0, z = 0;
- RSCoordinate() : x(), y(), z(){};
+ RSCoordinate() = default;
bool operator==(const lldb_renderscript::RSCoordinate &rhs) {
return x == rhs.x && y == rhs.y && z == rhs.z;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 211eb9ce0d3a..7ff917518b64 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -42,9 +42,7 @@ using namespace lldb_private;
LLDB_PLUGIN_DEFINE(ObjectContainerBSDArchive)
-ObjectContainerBSDArchive::Object::Object()
- : ar_name(), modification_time(0), uid(0), gid(0), mode(0), size(0),
- file_offset(0), file_size(0) {}
+ObjectContainerBSDArchive::Object::Object() : ar_name() {}
void ObjectContainerBSDArchive::Object::Clear() {
ar_name.Clear();
@@ -142,7 +140,7 @@ ObjectContainerBSDArchive::Archive::Archive(const lldb_private::ArchSpec &arch,
: m_arch(arch), m_modification_time(time), m_file_offset(file_offset),
m_objects(), m_data(data) {}
-ObjectContainerBSDArchive::Archive::~Archive() {}
+ObjectContainerBSDArchive::Archive::~Archive() = default;
size_t ObjectContainerBSDArchive::Archive::ParseObjects() {
DataExtractor &data = m_data;
@@ -375,7 +373,7 @@ void ObjectContainerBSDArchive::SetArchive(Archive::shared_ptr &archive_sp) {
m_archive_sp = archive_sp;
}
-ObjectContainerBSDArchive::~ObjectContainerBSDArchive() {}
+ObjectContainerBSDArchive::~ObjectContainerBSDArchive() = default;
bool ObjectContainerBSDArchive::ParseHeader() {
if (m_archive_sp.get() == nullptr) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index f6862afff8a0..9830e9b5d1b2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -84,25 +84,25 @@ protected:
lldb_private::ConstString ar_name;
/// Object modification time in the archive.
- uint32_t modification_time;
+ uint32_t modification_time = 0;
/// Object user id in the archive.
- uint16_t uid;
+ uint16_t uid = 0;
/// Object group id in the archive.
- uint16_t gid;
+ uint16_t gid = 0;
/// Object octal file permissions in the archive.
- uint16_t mode;
+ uint16_t mode = 0;
/// Object size in bytes in the archive.
- uint32_t size;
+ uint32_t size = 0;
/// File offset in bytes from the beginning of the file of the object data.
- lldb::offset_t file_offset;
+ lldb::offset_t file_offset = 0;
/// Length of the object data.
- lldb::offset_t file_size;
+ lldb::offset_t file_size = 0;
};
class Archive {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index cad9ce218b10..a5e86f0c2c1b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -16,6 +16,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/LZMA.h"
@@ -37,6 +38,7 @@
#include "llvm/Object/Decompressor.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/CRC.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MipsABIFlags.h"
@@ -857,8 +859,7 @@ Address ObjectFileELF::GetImageInfoAddress(Target *target) {
if (symbol.d_tag == DT_MIPS_RLD_MAP) {
// DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
Address addr;
- if (target->ReadPointerFromMemory(dyn_base + offset, false, error,
- addr))
+ if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true))
return addr;
}
if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
@@ -866,7 +867,7 @@ Address ObjectFileELF::GetImageInfoAddress(Target *target) {
// relative to the address of the tag.
uint64_t rel_offset;
rel_offset = target->ReadUnsignedIntegerFromMemory(
- dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
+ dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true);
if (error.Success() && rel_offset != UINT64_MAX) {
Address addr;
addr_t debug_ptr_address =
@@ -1861,7 +1862,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
// unified section list.
if (GetType() != eTypeDebugInfo)
unified_section_list = *m_sections_up;
-
+
// If there's a .gnu_debugdata section, we'll try to read the .symtab that's
// embedded in there and replace the one in the original object file (if any).
// If there's none in the orignal object file, we add it to it.
@@ -1879,7 +1880,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
unified_section_list.AddSection(symtab_section_sp);
}
}
- }
+ }
}
std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
@@ -1923,7 +1924,7 @@ std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture();
if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec))
return m_gnu_debug_data_object_file;
-
+
return nullptr;
}
@@ -2707,6 +2708,9 @@ Symtab *ObjectFileELF::GetSymtab() {
if (!module_sp)
return nullptr;
+ Progress progress(llvm::formatv("Parsing symbol table for {0}",
+ m_file.GetFilename().AsCString("<Unknown>")));
+
// We always want to use the main object file so we (hopefully) only have one
// cached copy of our symtab, dynamic sections, etc.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
@@ -2770,14 +2774,14 @@ Symtab *ObjectFileELF::GetSymtab() {
user_id_t reloc_id = reloc_section->GetID();
const ELFSectionHeaderInfo *reloc_header =
GetSectionHeaderByIndex(reloc_id);
- assert(reloc_header);
-
- if (m_symtab_up == nullptr)
- m_symtab_up =
- std::make_unique<Symtab>(reloc_section->GetObjectFile());
+ if (reloc_header) {
+ if (m_symtab_up == nullptr)
+ m_symtab_up =
+ std::make_unique<Symtab>(reloc_section->GetObjectFile());
- ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
- reloc_id);
+ ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
+ reloc_id);
+ }
}
}
@@ -2809,31 +2813,37 @@ Symtab *ObjectFileELF::GetSymtab() {
if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
entry_point_file_addr)) {
uint64_t symbol_id = m_symtab_up->GetNumSymbols();
- Symbol symbol(symbol_id,
- GetNextSyntheticSymbolName().GetCString(), // Symbol name.
- eSymbolTypeCode, // Type of this symbol.
- true, // Is this globally visible?
- false, // Is this symbol debug info?
- false, // Is this symbol a trampoline?
- true, // Is this symbol artificial?
- entry_point_addr.GetSection(), // Section where this
- // symbol is defined.
- 0, // Offset in section or symbol value.
- 0, // Size.
- false, // Size is valid.
- false, // Contains linker annotations?
- 0); // Symbol flags.
- m_symtab_up->AddSymbol(symbol);
+ // Don't set the name for any synthetic symbols, the Symbol
+ // object will generate one if needed when the name is accessed
+ // via accessors.
+ SectionSP section_sp = entry_point_addr.GetSection();
+ Symbol symbol(
+ /*symID=*/symbol_id,
+ /*name=*/llvm::StringRef(), // Name will be auto generated.
+ /*type=*/eSymbolTypeCode,
+ /*external=*/true,
+ /*is_debug=*/false,
+ /*is_trampoline=*/false,
+ /*is_artificial=*/true,
+ /*section_sp=*/section_sp,
+ /*offset=*/0,
+ /*size=*/0, // FDE can span multiple symbols so don't use its size.
+ /*size_is_valid=*/false,
+ /*contains_linker_annotations=*/false,
+ /*flags=*/0);
// When the entry point is arm thumb we need to explicitly set its
// class address to reflect that. This is important because expression
// evaluation relies on correctly setting a breakpoint at this
// address.
if (arch.GetMachine() == llvm::Triple::arm &&
- (entry_point_file_addr & 1))
+ (entry_point_file_addr & 1)) {
+ symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
m_address_class_map[entry_point_file_addr ^ 1] =
AddressClass::eCodeAlternateISA;
- else
+ } else {
m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
+ }
+ m_symtab_up->AddSymbol(symbol);
}
}
@@ -2897,8 +2907,11 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
// recalculate the index first.
std::vector<Symbol> new_symbols;
- eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
- lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
+ size_t num_symbols = symbol_table->GetNumSymbols();
+ uint64_t last_symbol_id =
+ num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0;
+ eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size,
+ dw_offset_t) {
Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
if (symbol) {
if (!symbol->GetByteSizeIsValid()) {
@@ -2910,22 +2923,24 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
section_list->FindSectionContainingFileAddress(file_addr);
if (section_sp) {
addr_t offset = file_addr - section_sp->GetFileAddress();
- const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
- uint64_t symbol_id = symbol_table->GetNumSymbols();
+ uint64_t symbol_id = ++last_symbol_id;
+ // Don't set the name for any synthetic symbols, the Symbol
+ // object will generate one if needed when the name is accessed
+ // via accessors.
Symbol eh_symbol(
- symbol_id, // Symbol table index.
- symbol_name, // Symbol name.
- eSymbolTypeCode, // Type of this symbol.
- true, // Is this globally visible?
- false, // Is this symbol debug info?
- false, // Is this symbol a trampoline?
- true, // Is this symbol artificial?
- section_sp, // Section in which this symbol is defined or null.
- offset, // Offset in section or symbol value.
- 0, // Size: Don't specify the size as an FDE can
- false, // Size is valid: cover multiple symbols.
- false, // Contains linker annotations?
- 0); // Symbol flags.
+ /*symID=*/symbol_id,
+ /*name=*/llvm::StringRef(), // Name will be auto generated.
+ /*type=*/eSymbolTypeCode,
+ /*external=*/true,
+ /*is_debug=*/false,
+ /*is_trampoline=*/false,
+ /*is_artificial=*/true,
+ /*section_sp=*/section_sp,
+ /*offset=*/offset,
+ /*size=*/0, // FDE can span multiple symbols so don't use its size.
+ /*size_is_valid=*/false,
+ /*contains_linker_annotations=*/false,
+ /*flags=*/0);
new_symbols.push_back(eh_symbol);
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 062271f1caf0..e678c2f5f011 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -9,7 +9,7 @@
#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
-#include <stdint.h>
+#include <cstdint>
#include <vector>
@@ -22,13 +22,13 @@
#include "ELFHeader.h"
struct ELFNote {
- elf::elf_word n_namesz;
- elf::elf_word n_descsz;
- elf::elf_word n_type;
+ elf::elf_word n_namesz = 0;
+ elf::elf_word n_descsz = 0;
+ elf::elf_word n_type = 0;
std::string n_name;
- ELFNote() : n_namesz(0), n_descsz(0), n_type(0) {}
+ ELFNote() = default;
/// Parse an ELFNote entry from the given DataExtractor starting at position
/// \p offset.
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index 93c2c9f945fe..f93ac9261afd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -100,7 +100,7 @@ ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp,
}
}
-ObjectFileJIT::~ObjectFileJIT() {}
+ObjectFileJIT::~ObjectFileJIT() = default;
bool ObjectFileJIT::ParseHeader() {
// JIT code is never in a file, nor is it required to have any header
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
index 35a823e9a28f..cb7bbeeca054 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
@@ -173,7 +173,7 @@ ObjectFilePDB::loadPDBFile(std::string PdbPath,
if (ec || magic != llvm::file_magic::pdb)
return nullptr;
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
- llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
+ llvm::MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
/*RequiresNullTerminator=*/false);
if (!ErrorOrBuffer)
return nullptr;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 6c29c2326212..5272da9ab33a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -196,7 +196,7 @@ bool ObjectFileWasm::DecodeNextSection(lldb::offset_t *offset_ptr) {
m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), section_length,
section_id, *sect_name});
*offset_ptr += (c.tell() + section_length);
- } else if (section_id <= llvm::wasm::WASM_SEC_EVENT) {
+ } else if (section_id <= llvm::wasm::WASM_SEC_TAG) {
m_sect_infos.push_back(section_info{*offset_ptr + c.tell(),
static_cast<uint32_t>(payload_len),
section_id, ConstString()});
diff --git a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index 4350010f0296..730c88f96e13 100644
--- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -91,13 +91,13 @@ OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process,
std::string os_plugin_class_name(
python_module_path.GetFilename().AsCString(""));
if (!os_plugin_class_name.empty()) {
- const bool init_session = false;
+ LoadScriptOptions options;
char python_module_path_cstr[PATH_MAX];
python_module_path.GetPath(python_module_path_cstr,
sizeof(python_module_path_cstr));
Status error;
- if (m_interpreter->LoadScriptingModule(python_module_path_cstr,
- init_session, error)) {
+ if (m_interpreter->LoadScriptingModule(python_module_path_cstr, options,
+ error)) {
// Strip the ".py" extension if there is one
size_t py_extension_pos = os_plugin_class_name.rfind(".py");
if (py_extension_pos != std::string::npos)
@@ -115,7 +115,7 @@ OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process,
}
}
-OperatingSystemPython::~OperatingSystemPython() {}
+OperatingSystemPython::~OperatingSystemPython() = default;
DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
if (m_register_info_up == nullptr) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 6b39a83fd668..7b3d8a375bf6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -9,7 +9,7 @@
#include "PlatformFreeBSD.h"
#include "lldb/Host/Config.h"
-#include <stdio.h>
+#include <cstdio>
#if LLDB_ENABLE_POSIX
#include <sys/utsname.h>
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index a5d73c942830..e3682b44e141 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -9,7 +9,7 @@
#include "PlatformNetBSD.h"
#include "lldb/Host/Config.h"
-#include <stdio.h>
+#include <cstdio>
#if LLDB_ENABLE_POSIX
#include <sys/utsname.h>
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index 2cd024f56ec9..012b688231a0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -9,7 +9,7 @@
#include "PlatformOpenBSD.h"
#include "lldb/Host/Config.h"
-#include <stdio.h>
+#include <cstdio>
#if LLDB_ENABLE_POSIX
#include <sys/utsname.h>
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 3628b0a2ce5e..7353132cd96f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -46,7 +46,7 @@ PlatformPOSIX::PlatformPOSIX(bool is_host)
///
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
-PlatformPOSIX::~PlatformPOSIX() {}
+PlatformPOSIX::~PlatformPOSIX() = default;
lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions(
lldb_private::CommandInterpreter &interpreter) {
@@ -578,7 +578,19 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
// __lldb_dlopen_result for consistency. The wrapper returns a void * but
// doesn't use it because UtilityFunctions don't work with void returns at
// present.
+ //
+ // Use lazy binding so as to not make dlopen()'s success conditional on
+ // forcing every symbol in the library.
+ //
+ // In general, the debugger should allow programs to load & run with
+ // libraries as far as they can, instead of defaulting to being super-picky
+ // about unavailable symbols.
+ //
+ // The value "1" appears to imply lazy binding (RTLD_LAZY) on both Darwin
+ // and other POSIX OSes.
static const char *dlopen_wrapper_code = R"(
+ const int RTLD_LAZY = 1;
+
struct __lldb_dlopen_result {
void *image_ptr;
const char *error_str;
@@ -595,7 +607,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
{
// This is the case where the name is the full path:
if (!path_strings) {
- result_ptr->image_ptr = dlopen(name, 2);
+ result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
if (result_ptr->image_ptr)
result_ptr->error_str = nullptr;
return nullptr;
@@ -609,7 +621,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
buffer[path_len] = '/';
char *target_ptr = buffer+path_len+1;
memcpy((void *) target_ptr, (void *) name, name_len + 1);
- result_ptr->image_ptr = dlopen(buffer, 2);
+ result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
if (result_ptr->image_ptr) {
result_ptr->error_str = nullptr;
break;
@@ -659,7 +671,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
// We are passing four arguments, the basename, the list of places to look,
// a buffer big enough for all the path + name combos, and
// a pointer to the storage we've made for the result:
- value.SetValueType(Value::eValueTypeScalar);
+ value.SetValueType(Value::ValueType::Scalar);
value.SetCompilerType(clang_void_pointer_type);
arguments.PushValue(value);
value.SetCompilerType(clang_char_pointer_type);
@@ -994,13 +1006,6 @@ PlatformPOSIX::GetLibdlFunctionDeclarations(lldb_private::Process *process) {
)";
}
-size_t PlatformPOSIX::ConnectToWaitingProcesses(Debugger &debugger,
- Status &error) {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
- return Platform::ConnectToWaitingProcesses(debugger, error);
-}
-
ConstString PlatformPOSIX::GetFullNameForDylib(ConstString basename) {
if (basename.IsEmpty())
return basename;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 72c54f4147c2..1cba4c5eb2e9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -71,9 +71,6 @@ public:
lldb_private::Status UnloadImage(lldb_private::Process *process,
uint32_t image_token) override;
- size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
- lldb_private::Status &error) override;
-
lldb_private::ConstString GetFullNameForDylib(lldb_private::ConstString basename) override;
protected:
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 6a4275d249f6..528208665a4e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -30,6 +30,7 @@
#include "lldb/Utility/UriParser.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -202,13 +203,16 @@ Status PlatformRemoteGDBServer::GetFileWithUUID(const FileSpec &platform_file,
/// Default Constructor
PlatformRemoteGDBServer::PlatformRemoteGDBServer()
: Platform(false), // This is a remote platform
- m_gdb_client() {}
+ m_gdb_client() {
+ m_gdb_client.SetPacketTimeout(
+ process_gdb_remote::ProcessGDBRemote::GetPacketTimeout());
+}
/// Destructor.
///
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
-PlatformRemoteGDBServer::~PlatformRemoteGDBServer() {}
+PlatformRemoteGDBServer::~PlatformRemoteGDBServer() = default;
bool PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
@@ -736,8 +740,8 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture());
StringExtractorGDBRemote response;
- auto result = m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo",
- response, false);
+ auto result =
+ m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", response);
if (result != decltype(result)::Success ||
response.GetResponseType() != response.eResponse)
@@ -839,7 +843,7 @@ size_t PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger &debugger,
GetPendingGdbServerList(connection_urls);
for (size_t i = 0; i < connection_urls.size(); ++i) {
- ConnectProcess(connection_urls[i].c_str(), "", debugger, nullptr, error);
+ ConnectProcess(connection_urls[i].c_str(), "gdb-remote", debugger, nullptr, error);
if (error.Fail())
return i; // We already connected to i process succsessfully
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
index 5961ff4439db..d6426b3d2367 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -128,13 +128,20 @@ NativeProcessFreeBSD::Factory::Attach(
return std::move(process_up);
}
+NativeProcessFreeBSD::Extension
+NativeProcessFreeBSD::Factory::GetSupportedExtensions() const {
+ return Extension::multiprocess | Extension::fork | Extension::vfork |
+ Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+}
+
// Public Instance Methods
NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid, int terminal_fd,
NativeDelegate &delegate,
const ArchSpec &arch,
MainLoop &mainloop)
- : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
+ : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
+ m_main_loop(mainloop) {
if (m_terminal_fd != -1) {
Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
assert(status.Success());
@@ -258,6 +265,26 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
info.pl_lwpid);
}
+ if (info.pl_flags & PL_FLAG_FORKED) {
+ assert(thread);
+ MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
+ return;
+ }
+
+ if (info.pl_flags & PL_FLAG_VFORK_DONE) {
+ assert(thread);
+ if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
+ thread->SetStoppedByVForkDone();
+ SetState(StateType::eStateStopped, true);
+ } else {
+ Status error =
+ PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+ if (error.Fail())
+ SetState(StateType::eStateInvalid);
+ }
+ return;
+ }
+
if (info.pl_flags & PL_FLAG_SI) {
assert(info.pl_siginfo.si_signo == SIGTRAP);
LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}",
@@ -705,17 +732,17 @@ NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
void NativeProcessFreeBSD::SigchldHandler() {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- // Process all pending waitpid notifications.
int status;
::pid_t wait_pid =
llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG);
if (wait_pid == 0)
- return; // We are done.
+ return;
if (wait_pid == -1) {
Status error(errno, eErrorTypePOSIX);
LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
+ return;
}
WaitStatus wait_status = WaitStatus::Decode(status);
@@ -885,7 +912,7 @@ Status NativeProcessFreeBSD::SetupTrace() {
PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
if (status.Fail())
return status;
- events |= PTRACE_LWP;
+ events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK;
status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
if (status.Fail())
return status;
@@ -919,3 +946,66 @@ Status NativeProcessFreeBSD::ReinitializeThreads() {
bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
return !m_arch.IsMIPS();
}
+
+void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
+ NativeThreadFreeBSD &parent_thread) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "fork, child_pid={0}", child_pid);
+
+ int status;
+ ::pid_t wait_pid =
+ llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
+ if (wait_pid != child_pid) {
+ LLDB_LOG(log,
+ "waiting for pid {0} failed. Assuming the pid has "
+ "disappeared in the meantime",
+ child_pid);
+ return;
+ }
+ if (WIFEXITED(status)) {
+ LLDB_LOG(log,
+ "waiting for pid {0} returned an 'exited' event. Not "
+ "tracking it.",
+ child_pid);
+ return;
+ }
+
+ struct ptrace_lwpinfo info;
+ const auto siginfo_err = PtraceWrapper(PT_LWPINFO, child_pid, &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+ return;
+ }
+ assert(info.pl_event == PL_EVENT_SIGNAL);
+ lldb::tid_t child_tid = info.pl_lwpid;
+
+ std::unique_ptr<NativeProcessFreeBSD> child_process{
+ new NativeProcessFreeBSD(static_cast<::pid_t>(child_pid), m_terminal_fd,
+ m_delegate, m_arch, m_main_loop)};
+ if (!is_vfork)
+ child_process->m_software_breakpoints = m_software_breakpoints;
+
+ Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+ if ((m_enabled_extensions & expected_ext) == expected_ext) {
+ child_process->SetupTrace();
+ for (const auto &thread : child_process->m_threads)
+ static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+ child_process->SetState(StateType::eStateStopped, false);
+
+ m_delegate.NewSubprocess(this, std::move(child_process));
+ if (is_vfork)
+ parent_thread.SetStoppedByVFork(child_pid, child_tid);
+ else
+ parent_thread.SetStoppedByFork(child_pid, child_tid);
+ SetState(StateType::eStateStopped, true);
+ } else {
+ child_process->Detach();
+ Status pt_error =
+ PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
+ if (pt_error.Fail()) {
+ LLDB_LOG_ERROR(log, pt_error.ToError(),
+ "unable to resume parent process {1}: {0}", GetID());
+ SetState(StateType::eStateInvalid);
+ }
+ }
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
index ceffc370ca33..7ec9d17d4cf4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
@@ -39,6 +39,8 @@ public:
llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
MainLoop &mainloop) const override;
+
+ Extension GetSupportedExtensions() const override;
};
// NativeProcessProtocol Interface
@@ -96,6 +98,7 @@ protected:
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
+ MainLoop& m_main_loop;
LazyBool m_supports_mem_region = eLazyBoolCalculate;
std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
@@ -113,6 +116,8 @@ private:
void MonitorSIGSTOP(lldb::pid_t pid);
void MonitorSIGTRAP(lldb::pid_t pid);
void MonitorSignal(lldb::pid_t pid, int signal);
+ void MonitorClone(::pid_t child_pid, bool is_vfork,
+ NativeThreadFreeBSD &parent_thread);
Status PopulateMemoryRegionCache();
void SigchldHandler();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
index e98e0a8a0caa..4578138a89b3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -37,14 +37,12 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
: NativeRegisterContextRegisterInfo(
- native_thread, new RegisterInfoPOSIX_arm64(target_arch))
+ native_thread, new RegisterInfoPOSIX_arm64(target_arch, 0))
#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
,
m_read_dbreg(false)
#endif
{
- GetRegisterInfo().ConfigureVectorRegisterInfos(
- RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64);
::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
}
@@ -79,8 +77,6 @@ Status NativeRegisterContextFreeBSD_arm64::ReadRegisterSet(uint32_t set) {
return NativeProcessFreeBSD::PtraceWrapper(
PT_GETFPREGS, m_thread.GetID(),
m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR));
- case RegisterInfoPOSIX_arm64::SVERegSet:
- return Status("not supported");
}
llvm_unreachable("NativeRegisterContextFreeBSD_arm64::ReadRegisterSet");
}
@@ -94,8 +90,6 @@ Status NativeRegisterContextFreeBSD_arm64::WriteRegisterSet(uint32_t set) {
return NativeProcessFreeBSD::PtraceWrapper(
PT_SETFPREGS, m_thread.GetID(),
m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR));
- case RegisterInfoPOSIX_arm64::SVERegSet:
- return Status("not supported");
}
llvm_unreachable("NativeRegisterContextFreeBSD_arm64::WriteRegisterSet");
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
index d5052e7d1b3a..9328d606ad26 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -260,7 +260,7 @@ NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
: NativeRegisterContextRegisterInfo(
native_thread, CreateRegisterInfoInterface(target_arch)),
- m_regset_offsets({0}) {
+ NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) {
assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
std::array<uint32_t, MaxRegSet + 1> first_regnos;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
index 63be12fc7b2b..80b3527aebce 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
@@ -130,6 +130,30 @@ void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
m_stop_info.details.signal.signo = SIGTRAP;
}
+void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid,
+ lldb::tid_t child_tid) {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonFork;
+ m_stop_info.details.fork.child_pid = child_pid;
+ m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadFreeBSD::SetStoppedByVFork(lldb::pid_t child_pid,
+ lldb::tid_t child_tid) {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonVFork;
+ m_stop_info.details.fork.child_pid = child_pid;
+ m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadFreeBSD::SetStoppedByVForkDone() {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
void NativeThreadFreeBSD::SetStoppedWithNoReason() {
SetStopped();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
index 249d2486b4f7..3ec6daa409e4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
@@ -59,6 +59,9 @@ private:
void SetStoppedByTrace();
void SetStoppedByExec();
void SetStoppedByWatchpoint(uint32_t wp_index);
+ void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+ void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+ void SetStoppedByVForkDone();
void SetStoppedWithNoReason();
void SetStopped();
void SetRunning();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 57f0eb3cceb6..9ea1a16b8785 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -133,13 +133,20 @@ NativeProcessNetBSD::Factory::Attach(
return std::move(process_up);
}
+NativeProcessNetBSD::Extension
+NativeProcessNetBSD::Factory::GetSupportedExtensions() const {
+ return Extension::multiprocess | Extension::fork | Extension::vfork |
+ Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+}
+
// Public Instance Methods
NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd,
NativeDelegate &delegate,
const ArchSpec &arch,
MainLoop &mainloop)
- : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
+ : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
+ m_main_loop(mainloop) {
if (m_terminal_fd != -1) {
Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
assert(status.Success());
@@ -256,6 +263,33 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
SetState(StateType::eStateStopped, true);
return;
}
+ case TRAP_CHLD: {
+ ptrace_state_t pst;
+ Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
+ if (error.Fail()) {
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+
+ assert(thread);
+ if (pst.pe_report_event == PTRACE_VFORK_DONE) {
+ if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
+ thread->SetStoppedByVForkDone();
+ SetState(StateType::eStateStopped, true);
+ } else {
+ Status error =
+ PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+ if (error.Fail())
+ SetState(StateType::eStateInvalid);
+ }
+ } else {
+ assert(pst.pe_report_event == PTRACE_FORK ||
+ pst.pe_report_event == PTRACE_VFORK);
+ MonitorClone(pst.pe_other_pid, pst.pe_report_event == PTRACE_VFORK,
+ *thread);
+ }
+ return;
+ }
case TRAP_LWP: {
ptrace_state_t pst;
Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
@@ -510,7 +544,7 @@ Status NativeProcessNetBSD::Detach() {
if (GetID() == LLDB_INVALID_PROCESS_ID)
return error;
- return PtraceWrapper(PT_DETACH, GetID());
+ return PtraceWrapper(PT_DETACH, GetID(), reinterpret_cast<void *>(1));
}
Status NativeProcessNetBSD::Signal(int signo) {
@@ -738,17 +772,17 @@ Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
void NativeProcessNetBSD::SigchldHandler() {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- // Process all pending waitpid notifications.
int status;
::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status,
WALLSIG | WNOHANG);
if (wait_pid == 0)
- return; // We are done.
+ return;
if (wait_pid == -1) {
Status error(errno, eErrorTypePOSIX);
LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
+ return;
}
WaitStatus wait_status = WaitStatus::Decode(status);
@@ -936,8 +970,9 @@ Status NativeProcessNetBSD::SetupTrace() {
PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
if (status.Fail())
return status;
- // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?
- events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
+ // TODO: PTRACE_POSIX_SPAWN?
+ events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT | PTRACE_FORK |
+ PTRACE_VFORK | PTRACE_VFORK_DONE;
status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
if (status.Fail())
return status;
@@ -974,3 +1009,67 @@ Status NativeProcessNetBSD::ReinitializeThreads() {
return error;
}
+
+void NativeProcessNetBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
+ NativeThreadNetBSD &parent_thread) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "clone, child_pid={0}", child_pid);
+
+ int status;
+ ::pid_t wait_pid =
+ llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
+ if (wait_pid != child_pid) {
+ LLDB_LOG(log,
+ "waiting for pid {0} failed. Assuming the pid has "
+ "disappeared in the meantime",
+ child_pid);
+ return;
+ }
+ if (WIFEXITED(status)) {
+ LLDB_LOG(log,
+ "waiting for pid {0} returned an 'exited' event. Not "
+ "tracking it.",
+ child_pid);
+ return;
+ }
+
+ ptrace_siginfo_t info;
+ const auto siginfo_err =
+ PtraceWrapper(PT_GET_SIGINFO, child_pid, &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_GET_SIGINFO failed {0}", siginfo_err);
+ return;
+ }
+ assert(info.psi_lwpid >= 0);
+ lldb::tid_t child_tid = info.psi_lwpid;
+
+ std::unique_ptr<NativeProcessNetBSD> child_process{
+ new NativeProcessNetBSD(static_cast<::pid_t>(child_pid), m_terminal_fd,
+ m_delegate, m_arch, m_main_loop)};
+ if (!is_vfork)
+ child_process->m_software_breakpoints = m_software_breakpoints;
+
+ Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+ if ((m_enabled_extensions & expected_ext) == expected_ext) {
+ child_process->SetupTrace();
+ for (const auto &thread : child_process->m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+ child_process->SetState(StateType::eStateStopped, false);
+
+ m_delegate.NewSubprocess(this, std::move(child_process));
+ if (is_vfork)
+ parent_thread.SetStoppedByVFork(child_pid, child_tid);
+ else
+ parent_thread.SetStoppedByFork(child_pid, child_tid);
+ SetState(StateType::eStateStopped, true);
+ } else {
+ child_process->Detach();
+ Status pt_error =
+ PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
+ if (pt_error.Fail()) {
+ LLDB_LOG_ERROR(log, std::move(pt_error.ToError()),
+ "unable to resume parent process {1}: {0}", GetID());
+ SetState(StateType::eStateInvalid);
+ }
+ }
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 3d59a4f72e94..90d32aa6069d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -36,6 +36,8 @@ public:
llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
MainLoop &mainloop) const override;
+
+ Extension GetSupportedExtensions() const override;
};
// NativeProcessProtocol Interface
@@ -89,6 +91,7 @@ public:
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
+ MainLoop& m_main_loop;
LazyBool m_supports_mem_region = eLazyBoolCalculate;
std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
@@ -106,6 +109,8 @@ private:
void MonitorSIGSTOP(lldb::pid_t pid);
void MonitorSIGTRAP(lldb::pid_t pid);
void MonitorSignal(lldb::pid_t pid, int signal);
+ void MonitorClone(::pid_t child_pid, bool is_vfork,
+ NativeThreadNetBSD &parent_thread);
Status PopulateMemoryRegionCache();
void SigchldHandler();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index ed1884c94a4b..3d164eadbea7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -29,8 +29,8 @@
#include <x86/specialreg.h>
#include <elf.h>
#include <err.h>
-#include <stdint.h>
-#include <stdlib.h>
+#include <cstdint>
+#include <cstdlib>
// clang-format on
using namespace lldb_private;
@@ -267,7 +267,7 @@ NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
: NativeRegisterContextRegisterInfo(
native_thread, CreateRegisterInfoInterface(target_arch)),
- m_regset_offsets({0}) {
+ NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) {
assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
std::array<uint32_t, MaxRegularRegSet + 1> first_regnos;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index 1a3fd4d646ae..400b89a5fddf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -130,6 +130,30 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
m_stop_info.details.signal.signo = SIGTRAP;
}
+void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid,
+ lldb::tid_t child_tid) {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonFork;
+ m_stop_info.details.fork.child_pid = child_pid;
+ m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadNetBSD::SetStoppedByVFork(lldb::pid_t child_pid,
+ lldb::tid_t child_tid) {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonVFork;
+ m_stop_info.details.fork.child_pid = child_pid;
+ m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadNetBSD::SetStoppedByVForkDone() {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
void NativeThreadNetBSD::SetStoppedWithNoReason() {
SetStopped();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
index d4e21bd2bdaa..ee9305337fda 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -59,6 +59,9 @@ private:
void SetStoppedByTrace();
void SetStoppedByExec();
void SetStoppedByWatchpoint(uint32_t wp_index);
+ void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+ void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+ void SetStoppedByVForkDone();
void SetStoppedWithNoReason();
void SetStopped();
void SetRunning();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
index f5213891d976..24acdc08e900 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
@@ -11,7 +11,7 @@
#include "lldb/lldb-types.h"
-#include <signal.h>
+#include <csignal>
#include <string>
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
index dcfa9290ff50..c01409940daa 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
@@ -21,6 +21,9 @@ namespace lldb_private {
class NativeProcessELF : public NativeProcessProtocol {
using NativeProcessProtocol::NativeProcessProtocol;
+public:
+ llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type);
+
protected:
template <typename T> struct ELFLinkMap {
T l_addr;
@@ -30,8 +33,6 @@ protected:
T l_prev;
};
- llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type);
-
lldb::addr_t GetSharedLibraryInfoAddress() override;
template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 5463a071503c..a85d7bd6f525 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -697,6 +697,14 @@ RegisterInfo *DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) {
return nullptr;
}
+const RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(uint32_t kind,
+ uint32_t num) const {
+ uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num);
+ if (reg_index != LLDB_INVALID_REGNUM)
+ return &m_regs[reg_index];
+ return nullptr;
+}
+
const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const {
if (i < m_sets.size())
return &m_sets[i];
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index fbf9db685b71..7e90454c6d9d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -60,6 +60,9 @@ public:
uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind,
uint32_t num) const;
+ const lldb_private::RegisterInfo *GetRegisterInfo(uint32_t kind,
+ uint32_t num) const;
+
void Dump() const;
void Clear();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 9b9522955de9..7749dc6f5d51 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -30,7 +30,7 @@ HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
// Destructor
-HistoryUnwind::~HistoryUnwind() {}
+HistoryUnwind::~HistoryUnwind() = default;
void HistoryUnwind::DoClear() {
std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
index 7f6f7cf5832d..817dca336de7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
@@ -9,7 +9,7 @@
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
-#include <stdint.h>
+#include <cstdint>
namespace lldb_private {
namespace sve {
@@ -65,7 +65,7 @@ const uint16_t sve_context_size = 16;
* The same convention applies when returning from a signal: a caller
* will need to remove or resize the sve_context block if it wants to
* make the SVE registers live when they were previously non-live or
- * vice-versa. This may require the the caller to allocate fresh
+ * vice-versa. This may require the caller to allocate fresh
* memory and/or move other context blocks in the signal frame.
*
* Changing the vector length during signal return is not permitted:
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp
new file mode 100644
index 000000000000..d74b66b58afc
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp
@@ -0,0 +1,200 @@
+//===-- MemoryTagManagerAArch64MTE.cpp --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MemoryTagManagerAArch64MTE.h"
+
+using namespace lldb_private;
+
+static const unsigned MTE_START_BIT = 56;
+static const unsigned MTE_TAG_MAX = 0xf;
+static const unsigned MTE_GRANULE_SIZE = 16;
+
+lldb::addr_t
+MemoryTagManagerAArch64MTE::GetLogicalTag(lldb::addr_t addr) const {
+ return (addr >> MTE_START_BIT) & MTE_TAG_MAX;
+}
+
+lldb::addr_t
+MemoryTagManagerAArch64MTE::RemoveNonAddressBits(lldb::addr_t addr) const {
+ // Here we're ignoring the whole top byte. If you've got MTE
+ // you must also have TBI (top byte ignore).
+ // The other 4 bits could contain other extension bits or
+ // user metadata.
+ return addr & ~((lldb::addr_t)0xFF << MTE_START_BIT);
+}
+
+ptrdiff_t MemoryTagManagerAArch64MTE::AddressDiff(lldb::addr_t addr1,
+ lldb::addr_t addr2) const {
+ return RemoveNonAddressBits(addr1) - RemoveNonAddressBits(addr2);
+}
+
+lldb::addr_t MemoryTagManagerAArch64MTE::GetGranuleSize() const {
+ return MTE_GRANULE_SIZE;
+}
+
+int32_t MemoryTagManagerAArch64MTE::GetAllocationTagType() const {
+ return eMTE_allocation;
+}
+
+size_t MemoryTagManagerAArch64MTE::GetTagSizeInBytes() const { return 1; }
+
+MemoryTagManagerAArch64MTE::TagRange
+MemoryTagManagerAArch64MTE::ExpandToGranule(TagRange range) const {
+ // Ignore reading a length of 0
+ if (!range.IsValid())
+ return range;
+
+ const size_t granule = GetGranuleSize();
+
+ // Align start down to granule start
+ lldb::addr_t new_start = range.GetRangeBase();
+ lldb::addr_t align_down_amount = new_start % granule;
+ new_start -= align_down_amount;
+
+ // Account for the distance we moved the start above
+ size_t new_len = range.GetByteSize() + align_down_amount;
+ // Then align up to the end of the granule
+ size_t align_up_amount = granule - (new_len % granule);
+ if (align_up_amount != granule)
+ new_len += align_up_amount;
+
+ return TagRange(new_start, new_len);
+}
+
+llvm::Expected<MemoryTagManager::TagRange>
+MemoryTagManagerAArch64MTE::MakeTaggedRange(
+ lldb::addr_t addr, lldb::addr_t end_addr,
+ const lldb_private::MemoryRegionInfos &memory_regions) const {
+ // First check that the range is not inverted.
+ // We must remove tags here otherwise an address with a higher
+ // tag value will always be > the other.
+ ptrdiff_t len = AddressDiff(end_addr, addr);
+ if (len <= 0) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "End address (0x%" PRIx64
+ ") must be greater than the start address (0x%" PRIx64 ")",
+ end_addr, addr);
+ }
+
+ // Region addresses will not have memory tags. So when searching
+ // we must use an untagged address.
+ MemoryRegionInfo::RangeType tag_range(RemoveNonAddressBits(addr), len);
+ tag_range = ExpandToGranule(tag_range);
+
+ // Make a copy so we can use the original for errors and the final return.
+ MemoryRegionInfo::RangeType remaining_range(tag_range);
+
+ // While there are parts of the range that don't have a matching tagged memory
+ // region
+ while (remaining_range.IsValid()) {
+ // Search for a region that contains the start of the range
+ MemoryRegionInfos::const_iterator region = std::find_if(
+ memory_regions.cbegin(), memory_regions.cend(),
+ [&remaining_range](const MemoryRegionInfo &region) {
+ return region.GetRange().Contains(remaining_range.GetRangeBase());
+ });
+
+ if (region == memory_regions.cend() ||
+ region->GetMemoryTagged() != MemoryRegionInfo::eYes) {
+ // Some part of this range is untagged (or unmapped) so error
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Address range 0x%" PRIx64 ":0x%" PRIx64
+ " is not in a memory tagged region",
+ tag_range.GetRangeBase(),
+ tag_range.GetRangeEnd());
+ }
+
+ // We've found some part of the range so remove that part and continue
+ // searching for the rest. Moving the base "slides" the range so we need to
+ // save/restore the original end. If old_end is less than the new base, the
+ // range will be set to have 0 size and we'll exit the while.
+ lldb::addr_t old_end = remaining_range.GetRangeEnd();
+ remaining_range.SetRangeBase(region->GetRange().GetRangeEnd());
+ remaining_range.SetRangeEnd(old_end);
+ }
+
+ // Every part of the range is contained within a tagged memory region.
+ return tag_range;
+}
+
+llvm::Expected<std::vector<lldb::addr_t>>
+MemoryTagManagerAArch64MTE::UnpackTagsData(const std::vector<uint8_t> &tags,
+ size_t granules /*=0*/) const {
+ // 0 means don't check the number of tags before unpacking
+ if (granules) {
+ size_t num_tags = tags.size() / GetTagSizeInBytes();
+ if (num_tags != granules) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Packed tag data size does not match expected number of tags. "
+ "Expected %zu tag(s) for %zu granule(s), got %zu tag(s).",
+ granules, granules, num_tags);
+ }
+ }
+
+ // (if bytes per tag was not 1, we would reconstruct them here)
+
+ std::vector<lldb::addr_t> unpacked;
+ unpacked.reserve(tags.size());
+ for (auto it = tags.begin(); it != tags.end(); ++it) {
+ // Check all tags are in range
+ if (*it > MTE_TAG_MAX) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Found tag 0x%x which is > max MTE tag value of 0x%x.", *it,
+ MTE_TAG_MAX);
+ }
+ unpacked.push_back(*it);
+ }
+
+ return unpacked;
+}
+
+llvm::Expected<std::vector<uint8_t>> MemoryTagManagerAArch64MTE::PackTags(
+ const std::vector<lldb::addr_t> &tags) const {
+ std::vector<uint8_t> packed;
+ packed.reserve(tags.size() * GetTagSizeInBytes());
+
+ for (auto tag : tags) {
+ if (tag > MTE_TAG_MAX) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Found tag 0x%" PRIx64
+ " which is > max MTE tag value of 0x%x.",
+ tag, MTE_TAG_MAX);
+ }
+ packed.push_back(static_cast<uint8_t>(tag));
+ }
+
+ return packed;
+}
+
+llvm::Expected<std::vector<lldb::addr_t>>
+MemoryTagManagerAArch64MTE::RepeatTagsForRange(
+ const std::vector<lldb::addr_t> &tags, TagRange range) const {
+ std::vector<lldb::addr_t> new_tags;
+
+ // If the range is not empty
+ if (range.IsValid()) {
+ if (tags.empty()) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Expected some tags to cover given range, got zero.");
+ }
+
+ // We assume that this range has already been expanded/aligned to granules
+ size_t granules = range.GetByteSize() / GetGranuleSize();
+ new_tags.reserve(granules);
+ for (size_t to_copy = 0; granules > 0; granules -= to_copy) {
+ to_copy = granules > tags.size() ? tags.size() : granules;
+ new_tags.insert(new_tags.end(), tags.begin(), tags.begin() + to_copy);
+ }
+ }
+
+ return new_tags;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h
new file mode 100644
index 000000000000..d4e8249da93f
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h
@@ -0,0 +1,53 @@
+//===-- MemoryTagManagerAArch64MTE.h ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H
+
+#include "lldb/Target/MemoryTagManager.h"
+
+namespace lldb_private {
+
+class MemoryTagManagerAArch64MTE : public MemoryTagManager {
+public:
+ // This enum is supposed to be shared for all of AArch64 but until
+ // there are more tag types than MTE, it will live here.
+ enum MTETagTypes {
+ eMTE_logical = 0,
+ eMTE_allocation = 1,
+ };
+
+ lldb::addr_t GetGranuleSize() const override;
+ int32_t GetAllocationTagType() const override;
+ size_t GetTagSizeInBytes() const override;
+
+ lldb::addr_t GetLogicalTag(lldb::addr_t addr) const override;
+ lldb::addr_t RemoveNonAddressBits(lldb::addr_t addr) const override;
+ ptrdiff_t AddressDiff(lldb::addr_t addr1, lldb::addr_t addr2) const override;
+
+ TagRange ExpandToGranule(TagRange range) const override;
+
+ llvm::Expected<TagRange> MakeTaggedRange(
+ lldb::addr_t addr, lldb::addr_t end_addr,
+ const lldb_private::MemoryRegionInfos &memory_regions) const override;
+
+ llvm::Expected<std::vector<lldb::addr_t>>
+ UnpackTagsData(const std::vector<uint8_t> &tags,
+ size_t granules = 0) const override;
+
+ llvm::Expected<std::vector<uint8_t>>
+ PackTags(const std::vector<lldb::addr_t> &tags) const override;
+
+ llvm::Expected<std::vector<lldb::addr_t>>
+ RepeatTagsForRange(const std::vector<lldb::addr_t> &tags,
+ TagRange range) const override;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
index 5c05baf71764..feee857cfe5f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
@@ -421,6 +421,9 @@ Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex(
if (error)
return Status(std::move(error));
+ // Mask off ignored bits from watchpoint trap address.
+ trap_addr = FixWatchpointHitAddress(trap_addr);
+
uint32_t watch_size;
lldb::addr_t watch_addr;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
index 12ef5571f64c..3da0b0407ce6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
@@ -72,6 +72,9 @@ protected:
virtual llvm::Error ReadHardwareDebugInfo() = 0;
virtual llvm::Error WriteHardwareDebugRegs(DREGType hwbType) = 0;
+ virtual lldb::addr_t FixWatchpointHitAddress(lldb::addr_t hit_addr) {
+ return hit_addr;
+ }
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
index c0c6ce29eab5..a4ed8bfb97ea 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
@@ -16,6 +16,12 @@ namespace lldb_private {
class NativeRegisterContextDBReg_x86
: public virtual NativeRegisterContextRegisterInfo {
public:
+ // NB: This constructor is here only because gcc<=6.5 requires a virtual base
+ // class initializer on abstract class (even though it is never used). It can
+ // be deleted once we move to gcc>=7.0.
+ NativeRegisterContextDBReg_x86(NativeThreadProtocol &thread)
+ : NativeRegisterContextRegisterInfo(thread, nullptr) {}
+
Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
Status GetWatchpointHitIndex(uint32_t &wp_index,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index eef4541e7edd..7e38091738e3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -922,7 +922,7 @@ RegisterContextDarwin_arm::RegisterContextDarwin_arm(
}
}
-RegisterContextDarwin_arm::~RegisterContextDarwin_arm() {}
+RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default;
void RegisterContextDarwin_arm::InvalidateAllRegisters() {
InvalidateAllRegisterStates();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 9fc275276699..b98b2f35c23e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -104,7 +104,7 @@ RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(
}
}
-RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() {}
+RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() = default;
void RegisterContextDarwin_arm64::InvalidateAllRegisters() {
InvalidateAllRegisterStates();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index c5ebddc56b6c..95f8132a990c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -15,7 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
-#include <stddef.h>
+#include <cstddef>
#include <memory>
@@ -405,7 +405,7 @@ RegisterContextDarwin_i386::RegisterContextDarwin_i386(
}
}
-RegisterContextDarwin_i386::~RegisterContextDarwin_i386() {}
+RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default;
void RegisterContextDarwin_i386::InvalidateAllRegisters() {
InvalidateAllRegisterStates();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index 38cd00aea9cc..03e5ea424e39 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stddef.h>
+#include <cinttypes>
+#include <cstdarg>
+#include <cstddef>
#include <memory>
@@ -467,7 +467,7 @@ RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64(
}
}
-RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() {}
+RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default;
void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
InvalidateAllRegisterStates();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
index 9fe6255d698e..2991bd3c5f2c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
@@ -178,7 +178,7 @@ RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(
const ArchSpec &target_arch)
: RegisterInfoInterface(target_arch) {}
-RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() {}
+RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() = default;
size_t RegisterContextFreeBSD_powerpc::GetGPRSize() const {
// This is an 'abstract' base, so no GPR struct.
@@ -197,7 +197,7 @@ RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(
const ArchSpec &target_arch)
: RegisterContextFreeBSD_powerpc(target_arch) {}
-RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() {}
+RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() = default;
size_t RegisterContextFreeBSD_powerpc32::GetGPRSize() const {
return sizeof(GPR32);
@@ -217,7 +217,7 @@ RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(
const ArchSpec &target_arch)
: RegisterContextFreeBSD_powerpc(target_arch) {}
-RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() {}
+RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() = default;
size_t RegisterContextFreeBSD_powerpc64::GetGPRSize() const {
return sizeof(GPR64);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
deleted file mode 100644
index 837549e2a495..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- RegisterContextLinux_mips.cpp -------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===---------------------------------------------------------------------===//
-
-#include <stddef.h>
-#include <vector>
-
-// For eh_frame and DWARF Register numbers
-#include "RegisterContextLinux_mips.h"
-
-// Internal codes for mips registers
-#include "lldb-mips-linux-register-enums.h"
-
-// For GP and FP buffers
-#include "RegisterContext_mips.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-// Include RegisterInfos_mips to declare our g_register_infos_mips structure.
-#define DECLARE_REGISTER_INFOS_MIPS_STRUCT
-#include "RegisterInfos_mips.h"
-#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-
-// mips general purpose registers.
-const uint32_t g_gp_regnums_mips[] = {
- gpr_zero_mips, gpr_r1_mips, gpr_r2_mips, gpr_r3_mips,
- gpr_r4_mips, gpr_r5_mips, gpr_r6_mips, gpr_r7_mips,
- gpr_r8_mips, gpr_r9_mips, gpr_r10_mips, gpr_r11_mips,
- gpr_r12_mips, gpr_r13_mips, gpr_r14_mips, gpr_r15_mips,
- gpr_r16_mips, gpr_r17_mips, gpr_r18_mips, gpr_r19_mips,
- gpr_r20_mips, gpr_r21_mips, gpr_r22_mips, gpr_r23_mips,
- gpr_r24_mips, gpr_r25_mips, gpr_r26_mips, gpr_r27_mips,
- gpr_gp_mips, gpr_sp_mips, gpr_r30_mips, gpr_ra_mips,
- gpr_sr_mips, gpr_mullo_mips, gpr_mulhi_mips, gpr_badvaddr_mips,
- gpr_cause_mips, gpr_pc_mips, gpr_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 ==
- k_num_gpr_registers_mips,
- "g_gp_regnums_mips has wrong number of register infos");
-// mips floating point registers.
-const uint32_t g_fp_regnums_mips[] = {
- fpr_f0_mips, fpr_f1_mips, fpr_f2_mips, fpr_f3_mips,
- fpr_f4_mips, fpr_f5_mips, fpr_f6_mips, fpr_f7_mips,
- fpr_f8_mips, fpr_f9_mips, fpr_f10_mips, fpr_f11_mips,
- fpr_f12_mips, fpr_f13_mips, fpr_f14_mips, fpr_f15_mips,
- fpr_f16_mips, fpr_f17_mips, fpr_f18_mips, fpr_f19_mips,
- fpr_f20_mips, fpr_f21_mips, fpr_f22_mips, fpr_f23_mips,
- fpr_f24_mips, fpr_f25_mips, fpr_f26_mips, fpr_f27_mips,
- fpr_f28_mips, fpr_f29_mips, fpr_f30_mips, fpr_f31_mips,
- fpr_fcsr_mips, fpr_fir_mips, fpr_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 ==
- k_num_fpr_registers_mips,
- "g_fp_regnums_mips has wrong number of register infos");
-
-// mips MSA registers.
-const uint32_t g_msa_regnums_mips[] = {
- msa_w0_mips, msa_w1_mips, msa_w2_mips, msa_w3_mips,
- msa_w4_mips, msa_w5_mips, msa_w6_mips, msa_w7_mips,
- msa_w8_mips, msa_w9_mips, msa_w10_mips, msa_w11_mips,
- msa_w12_mips, msa_w13_mips, msa_w14_mips, msa_w15_mips,
- msa_w16_mips, msa_w17_mips, msa_w18_mips, msa_w19_mips,
- msa_w20_mips, msa_w21_mips, msa_w22_mips, msa_w23_mips,
- msa_w24_mips, msa_w25_mips, msa_w26_mips, msa_w27_mips,
- msa_w28_mips, msa_w29_mips, msa_w30_mips, msa_w31_mips,
- msa_fcsr_mips, msa_fir_mips, msa_mcsr_mips, msa_mir_mips,
- msa_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) -
- 1 ==
- k_num_msa_registers_mips,
- "g_msa_regnums_mips has wrong number of register infos");
-
-// Number of register sets provided by this context.
-constexpr size_t k_num_register_sets = 3;
-
-// Register sets for mips.
-static const RegisterSet g_reg_sets_mips[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_mips,
- g_gp_regnums_mips},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_mips,
- g_fp_regnums_mips},
- {"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}};
-
-uint32_t GetUserRegisterInfoCount(bool msa_present) {
- if (msa_present)
- return static_cast<uint32_t>(k_num_user_registers_mips);
- return static_cast<uint32_t>(k_num_user_registers_mips -
- k_num_msa_registers_mips);
-}
-
-RegisterContextLinux_mips::RegisterContextLinux_mips(
- const ArchSpec &target_arch, bool msa_present)
- : RegisterInfoInterface(target_arch),
- m_user_register_count(GetUserRegisterInfoCount(msa_present)) {}
-
-size_t RegisterContextLinux_mips::GetGPRSize() const {
- return sizeof(GPR_linux_mips);
-}
-
-const RegisterInfo *RegisterContextLinux_mips::GetRegisterInfo() const {
- switch (m_target_arch.GetMachine()) {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return g_register_infos_mips;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-}
-
-const RegisterSet *
-RegisterContextLinux_mips::GetRegisterSet(size_t set) const {
- if (set >= k_num_register_sets)
- return nullptr;
- switch (m_target_arch.GetMachine()) {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return &g_reg_sets_mips[set];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-}
-
-size_t
-RegisterContextLinux_mips::GetRegisterSetCount() const {
- return k_num_register_sets;
-}
-
-uint32_t RegisterContextLinux_mips::GetRegisterCount() const {
- return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
- sizeof(g_register_infos_mips[0]));
-}
-
-uint32_t RegisterContextLinux_mips::GetUserRegisterCount() const {
- return static_cast<uint32_t>(m_user_register_count);
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
deleted file mode 100644
index 9b59ab421ff4..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextLinux_mips.h ---------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H
-
-#include "RegisterInfoInterface.h"
-#include "lldb/lldb-private.h"
-
-class RegisterContextLinux_mips : public lldb_private::RegisterInfoInterface {
-public:
- RegisterContextLinux_mips(const lldb_private::ArchSpec &target_arch,
- bool msa_present = true);
-
- size_t GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *GetRegisterInfo() const override;
-
- const lldb_private::RegisterSet *GetRegisterSet(size_t set) const;
-
- size_t GetRegisterSetCount() const;
-
- uint32_t GetRegisterCount() const override;
-
- uint32_t GetUserRegisterCount() const override;
-
-private:
- uint32_t m_user_register_count;
-};
-
-#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
deleted file mode 100644
index 432a78129fde..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-//===-- RegisterContextLinux_mips64.cpp -----------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===---------------------------------------------------------------------===//
-
-
-#include <stddef.h>
-#include <vector>
-
-// For eh_frame and DWARF Register numbers
-#include "RegisterContextLinux_mips64.h"
-
-// For GP and FP buffers
-#include "RegisterContext_mips.h"
-
-// Internal codes for all mips32 and mips64 registers
-#include "lldb-mips-linux-register-enums.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// Include RegisterInfos_mips64 to declare our g_register_infos_mips64
-// structure.
-#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
-#define LINUX_MIPS64
-#include "RegisterInfos_mips64.h"
-#undef LINUX_MIPS64
-#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
-
-// Include RegisterInfos_mips to declare our g_register_infos_mips structure.
-#define DECLARE_REGISTER_INFOS_MIPS_STRUCT
-#include "RegisterInfos_mips.h"
-#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-
-// mips64 general purpose registers.
-const uint32_t g_gp_regnums_mips64[] = {
- gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64,
- gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64,
- gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64,
- gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
- gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64,
- gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64,
- gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64,
- gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
- gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64,
- gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64,
- gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64,
- gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
- gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
- 1 ==
- k_num_gpr_registers_mips64,
- "g_gp_regnums_mips64 has wrong number of register infos");
-
-// mips64 floating point registers.
-const uint32_t g_fp_regnums_mips64[] = {
- fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64,
- fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64,
- fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64,
- fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
- fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
- fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
- fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
- fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
- fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
- 1 ==
- k_num_fpr_registers_mips64,
- "g_fp_regnums_mips64 has wrong number of register infos");
-
-// mips64 MSA registers.
-const uint32_t g_msa_regnums_mips64[] = {
- msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64,
- msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64,
- msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64,
- msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64,
- msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64,
- msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64,
- msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64,
- msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64,
- msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
- msa_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
- 1 ==
- k_num_msa_registers_mips64,
- "g_msa_regnums_mips64 has wrong number of register infos");
-
-// Number of register sets provided by this context.
-constexpr size_t k_num_register_sets = 3;
-
-// Register sets for mips64.
-static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
- g_gp_regnums_mips64},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
- g_fp_regnums_mips64},
- {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
-};
-
-const RegisterSet *
-RegisterContextLinux_mips64::GetRegisterSet(size_t set) const {
- if (set >= k_num_register_sets)
- return nullptr;
-
- switch (m_target_arch.GetMachine()) {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return &g_reg_sets_mips64[set];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
- return nullptr;
-}
-
-size_t
-RegisterContextLinux_mips64::GetRegisterSetCount() const {
- return k_num_register_sets;
-}
-
-static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return g_register_infos_mips64;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return g_register_infos_mips;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-}
-
-static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
- sizeof(g_register_infos_mips64[0]));
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
- sizeof(g_register_infos_mips[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
-}
-
-uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch,
- bool msa_present) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- if (msa_present)
- return static_cast<uint32_t>(k_num_user_registers_mips);
- return static_cast<uint32_t>(k_num_user_registers_mips -
- k_num_msa_registers_mips);
- case llvm::Triple::mips64el:
- case llvm::Triple::mips64:
- if (msa_present)
- return static_cast<uint32_t>(k_num_user_registers_mips64);
- return static_cast<uint32_t>(k_num_user_registers_mips64 -
- k_num_msa_registers_mips64);
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
-}
-
-RegisterContextLinux_mips64::RegisterContextLinux_mips64(
- const ArchSpec &target_arch, bool msa_present)
- : lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch)),
- m_user_register_count(
- GetUserRegisterInfoCount(target_arch, msa_present)) {}
-
-size_t RegisterContextLinux_mips64::GetGPRSize() const {
- return sizeof(GPR_linux_mips);
-}
-
-const RegisterInfo *RegisterContextLinux_mips64::GetRegisterInfo() const {
- return m_register_info_p;
-}
-
-uint32_t RegisterContextLinux_mips64::GetRegisterCount() const {
- return m_register_info_count;
-}
-
-uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
- return m_user_register_count;
-}
-
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
deleted file mode 100644
index 899f0a40e4ae..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- RegisterContextLinux_mips64.h ---------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H
-
-#include "RegisterInfoInterface.h"
-#include "lldb/lldb-private.h"
-
-class RegisterContextLinux_mips64 : public lldb_private::RegisterInfoInterface {
-public:
- RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch,
- bool msa_present = true);
-
- size_t GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *GetRegisterInfo() const override;
-
- const lldb_private::RegisterSet *GetRegisterSet(size_t set) const;
-
- size_t GetRegisterSetCount() const;
-
- uint32_t GetRegisterCount() const override;
-
- uint32_t GetUserRegisterCount() const override;
-
-private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
- uint32_t m_user_register_count;
-};
-
-#endif
-
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index 1394cb7f00a1..067d1c3705e4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -21,7 +21,7 @@ RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread,
uint32_t concrete_frame_idx)
: RegisterContextDarwin_arm(thread, concrete_frame_idx) {}
-RegisterContextMach_arm::~RegisterContextMach_arm() {}
+RegisterContextMach_arm::~RegisterContextMach_arm() = default;
int RegisterContextMach_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
mach_msg_type_number_t count = GPRWordCount;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index b97166b6eebe..fe5cecef1b0c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -19,7 +19,7 @@ RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread,
uint32_t concrete_frame_idx)
: RegisterContextDarwin_i386(thread, concrete_frame_idx) {}
-RegisterContextMach_i386::~RegisterContextMach_i386() {}
+RegisterContextMach_i386::~RegisterContextMach_i386() = default;
int RegisterContextMach_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
mach_msg_type_number_t count = GPRWordCount;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index 8933f136789f..a3d8c4f649d2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -19,7 +19,7 @@ RegisterContextMach_x86_64::RegisterContextMach_x86_64(
Thread &thread, uint32_t concrete_frame_idx)
: RegisterContextDarwin_x86_64(thread, concrete_frame_idx) {}
-RegisterContextMach_x86_64::~RegisterContextMach_x86_64() {}
+RegisterContextMach_x86_64::~RegisterContextMach_x86_64() = default;
int RegisterContextMach_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
GPR &gpr) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index f2d230b54053..c55ffebb03e7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -39,7 +39,7 @@ RegisterContextMemory::RegisterContextMemory(Thread &thread,
}
// Destructor
-RegisterContextMemory::~RegisterContextMemory() {}
+RegisterContextMemory::~RegisterContextMemory() = default;
void RegisterContextMemory::InvalidateAllRegisters() {
if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 97a760396ba9..684176bccdf0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include <cerrno>
+#include <cstdint>
#include <cstring>
-#include <errno.h>
-#include <stdint.h>
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -45,7 +45,7 @@ RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(
: lldb_private::RegisterContext(thread, 0),
m_register_info_up(std::move(register_info)) {}
-RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {}
+RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() = default;
void RegisterContextPOSIX_arm::Invalidate() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 3f52501c35f3..676e450c4846 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include <cerrno>
+#include <cstdint>
#include <cstring>
-#include <errno.h>
-#include <stdint.h>
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -40,10 +40,11 @@ bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) {
}
bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const {
- if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
- RegisterInfoPOSIX_arm64::SVERegSet)
- return true;
- return false;
+ return m_register_info_up->IsSVEReg(reg);
+}
+
+bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const {
+ return m_register_info_up->IsPAuthReg(reg);
}
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
@@ -52,7 +53,7 @@ RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
: lldb_private::RegisterContext(thread, 0),
m_register_info_up(std::move(register_info)) {}
-RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {}
+RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() = default;
void RegisterContextPOSIX_arm64::Invalidate() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index a3f07bb2823b..7c301599d3af 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -54,6 +54,7 @@ protected:
size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); }
bool IsSVE(unsigned reg) const;
+ bool IsPAuth(unsigned reg) const;
bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); }
bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index c41c4bd7a7ea..9e05737d8e62 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include <cerrno>
+#include <cstdint>
#include <cstring>
-#include <errno.h>
-#include <stdint.h>
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -22,8 +22,6 @@
#include "RegisterContextPOSIX_mips64.h"
#include "RegisterContextFreeBSD_mips64.h"
-#include "RegisterContextLinux_mips64.h"
-#include "RegisterContextLinux_mips.h"
using namespace lldb_private;
using namespace lldb;
@@ -60,7 +58,7 @@ RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
m_registers_count[msa_registers_count]));
}
-RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {}
+RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() = default;
void RegisterContextPOSIX_mips64::Invalidate() {}
@@ -102,17 +100,6 @@ RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) {
size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
ArchSpec target_arch = m_register_info_up->GetTargetArchitecture();
switch (target_arch.GetTriple().getOS()) {
- case llvm::Triple::Linux: {
- if ((target_arch.GetMachine() == llvm::Triple::mipsel) ||
- (target_arch.GetMachine() == llvm::Triple::mips)) {
- const auto *context = static_cast<const RegisterContextLinux_mips *>(
- m_register_info_up.get());
- return context->GetRegisterSetCount();
- }
- const auto *context = static_cast<const RegisterContextLinux_mips64 *>(
- m_register_info_up.get());
- return context->GetRegisterSetCount();
- }
default: {
const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>(
m_register_info_up.get());
@@ -125,17 +112,6 @@ size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) {
ArchSpec target_arch = m_register_info_up->GetTargetArchitecture();
switch (target_arch.GetTriple().getOS()) {
- case llvm::Triple::Linux: {
- if ((target_arch.GetMachine() == llvm::Triple::mipsel) ||
- (target_arch.GetMachine() == llvm::Triple::mips)) {
- const auto *context = static_cast<const RegisterContextLinux_mips *>(
- m_register_info_up.get());
- return context->GetRegisterSet(set);
- }
- const auto *context = static_cast<const RegisterContextLinux_mips64 *>(
- m_register_info_up.get());
- return context->GetRegisterSet(set);
- }
default: {
const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>(
m_register_info_up.get());
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index cd65b96d373e..cffd2865e385 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include <cerrno>
+#include <cstdint>
#include <cstring>
-#include <errno.h>
-#include <stdint.h>
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -95,7 +95,7 @@ RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(
m_register_info_up.reset(register_info);
}
-RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() {}
+RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() = default;
void RegisterContextPOSIX_powerpc::Invalidate() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
index f670be2ef3c4..f70ddeba209c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include <cerrno>
+#include <cstdint>
#include <cstring>
-#include <errno.h>
-#include <stdint.h>
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
index e746ec642b38..21c8160e5b41 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include <cerrno>
+#include <cstdint>
#include <cstring>
-#include <errno.h>
-#include <stdint.h>
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -98,7 +98,7 @@ RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(
}
}
-RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() {}
+RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() = default;
void RegisterContextPOSIX_s390x::Invalidate() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 2c7f63503d7c..67e03ff1ea39 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include <cerrno>
+#include <cstdint>
#include <cstring>
-#include <errno.h>
-#include <stdint.h>
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -448,7 +448,7 @@ RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(
m_fpr_type = eNotValid;
}
-RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() {}
+RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() = default;
RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() {
if (m_fpr_type == eNotValid) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
index 31e2944084ed..4866cbd235e8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
@@ -22,7 +22,7 @@ RegisterContextThreadMemory::RegisterContextThreadMemory(
: RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()),
m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {}
-RegisterContextThreadMemory::~RegisterContextThreadMemory() {}
+RegisterContextThreadMemory::~RegisterContextThreadMemory() = default;
void RegisterContextThreadMemory::UpdateRegisterContext() {
ThreadSP thread_sp(m_thread_wp.lock());
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 88c2ae7c5010..c05438338c88 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -22,7 +22,7 @@ class RegisterInfoInterface {
public:
RegisterInfoInterface(const lldb_private::ArchSpec &target_arch)
: m_target_arch(target_arch) {}
- virtual ~RegisterInfoInterface() {}
+ virtual ~RegisterInfoInterface() = default;
virtual size_t GetGPRSize() const = 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
index 17b96f944cda..63461f7ab2db 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
@@ -7,7 +7,7 @@
//===---------------------------------------------------------------------===//
#include <cassert>
-#include <stddef.h>
+#include <cstddef>
#include <vector>
#include "lldb/lldb-defines.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index 515c9f44e1e2..b878534b39db 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -7,7 +7,7 @@
//===---------------------------------------------------------------------===//
#include <cassert>
-#include <stddef.h>
+#include <cstddef>
#include <vector>
#include "lldb/lldb-defines.h"
@@ -72,23 +72,14 @@
#include "RegisterInfos_arm64_sve.h"
#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
-static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_32:
- return g_register_infos_arm64_le;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-}
-
// Number of register sets provided by this context.
enum {
k_num_gpr_registers = gpr_w28 - gpr_x0 + 1,
k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1,
k_num_sve_registers = sve_ffr - sve_vg + 1,
+ k_num_mte_register = 1,
+ k_num_pauth_register = 2,
+ k_num_register_sets_default = 2,
k_num_register_sets = 3
};
@@ -186,31 +177,66 @@ static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
{"Scalable Vector Extension Registers", "sve", k_num_sve_registers,
g_sve_regnums_arm64}};
-static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+static const lldb_private::RegisterSet g_reg_set_pauth_arm64 = {
+ "Pointer Authentication Registers", "pauth", k_num_pauth_register, NULL};
+
+static const lldb_private::RegisterSet g_reg_set_mte_arm64 = {
+ "MTE Control Register", "mte", k_num_mte_register, NULL};
+
+RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
+ const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets)
+ : lldb_private::RegisterInfoAndSetInterface(target_arch),
+ m_opt_regsets(opt_regsets) {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_32:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
- sizeof(g_register_infos_arm64_le[0]));
+ case llvm::Triple::aarch64_32: {
+ m_register_set_p = g_reg_sets_arm64;
+ m_register_set_count = k_num_register_sets_default;
+ m_per_regset_regnum_range[GPRegSet] = std::make_pair(gpr_x0, gpr_w28 + 1);
+ m_per_regset_regnum_range[FPRegSet] = std::make_pair(fpu_v0, fpu_fpcr + 1);
+
+ // Now configure register sets supported by current target. If we have a
+ // dynamic register set like MTE, Pointer Authentication regset then we need
+ // to create dynamic register infos and regset array. Push back all optional
+ // register infos and regset and calculate register offsets accordingly.
+ if (m_opt_regsets.AllSet(eRegsetMaskSVE)) {
+ m_register_info_p = g_register_infos_arm64_sve_le;
+ m_register_info_count = sve_ffr + 1;
+ m_per_regset_regnum_range[m_register_set_count++] =
+ std::make_pair(sve_vg, sve_ffr + 1);
+ } else {
+ m_register_info_p = g_register_infos_arm64_le;
+ m_register_info_count = fpu_fpcr + 1;
+ }
+
+ if (m_opt_regsets.AnySet(eRegsetMaskDynamic)) {
+ llvm::ArrayRef<lldb_private::RegisterInfo> reg_infos_ref =
+ llvm::makeArrayRef(m_register_info_p, m_register_info_count);
+ llvm::ArrayRef<lldb_private::RegisterSet> reg_sets_ref =
+ llvm::makeArrayRef(m_register_set_p, m_register_set_count);
+ llvm::copy(reg_infos_ref, std::back_inserter(m_dynamic_reg_infos));
+ llvm::copy(reg_sets_ref, std::back_inserter(m_dynamic_reg_sets));
+
+ if (m_opt_regsets.AllSet(eRegsetMaskPAuth))
+ AddRegSetPAuth();
+
+ if (m_opt_regsets.AllSet(eRegsetMaskMTE))
+ AddRegSetMTE();
+
+ m_register_info_count = m_dynamic_reg_infos.size();
+ m_register_info_p = m_dynamic_reg_infos.data();
+ m_register_set_p = m_dynamic_reg_sets.data();
+ m_register_set_count = m_dynamic_reg_sets.size();
+ }
+ break;
+ }
default:
assert(false && "Unhandled target architecture.");
- return 0;
}
}
-RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
- const lldb_private::ArchSpec &target_arch)
- : lldb_private::RegisterInfoAndSetInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch)) {
-}
-
uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
- if (IsSVEEnabled())
- return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers;
-
- return k_num_gpr_registers + k_num_fpr_registers;
+ return m_register_info_count;
}
size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
@@ -227,31 +253,60 @@ RegisterInfoPOSIX_arm64::GetRegisterInfo() const {
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const {
- if (IsSVEEnabled())
- return k_num_register_sets;
- return k_num_register_sets - 1;
+ return m_register_set_count;
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex(
uint32_t reg_index) const {
- if (reg_index <= gpr_w28)
- return GPRegSet;
- if (reg_index <= fpu_fpcr)
- return FPRegSet;
- if (reg_index <= sve_ffr)
- return SVERegSet;
+ for (const auto &regset_range : m_per_regset_regnum_range) {
+ if (reg_index >= regset_range.second.first &&
+ reg_index < regset_range.second.second)
+ return regset_range.first;
+ }
return LLDB_INVALID_REGNUM;
}
const lldb_private::RegisterSet *
RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const {
if (set_index < GetRegisterSetCount())
- return &g_reg_sets_arm64[set_index];
+ return &m_register_set_p[set_index];
return nullptr;
}
-uint32_t
-RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
+void RegisterInfoPOSIX_arm64::AddRegSetPAuth() {
+ uint32_t pa_regnum = m_dynamic_reg_infos.size();
+ for (uint32_t i = 0; i < k_num_pauth_register; i++) {
+ pauth_regnum_collection.push_back(pa_regnum + i);
+ m_dynamic_reg_infos.push_back(g_register_infos_pauth[i]);
+ m_dynamic_reg_infos[pa_regnum + i].byte_offset =
+ m_dynamic_reg_infos[pa_regnum + i - 1].byte_offset +
+ m_dynamic_reg_infos[pa_regnum + i - 1].byte_size;
+ m_dynamic_reg_infos[pa_regnum + i].kinds[lldb::eRegisterKindLLDB] =
+ pa_regnum + i;
+ }
+
+ m_per_regset_regnum_range[m_register_set_count] =
+ std::make_pair(pa_regnum, m_dynamic_reg_infos.size());
+ m_dynamic_reg_sets.push_back(g_reg_set_pauth_arm64);
+ m_dynamic_reg_sets.back().registers = pauth_regnum_collection.data();
+}
+
+void RegisterInfoPOSIX_arm64::AddRegSetMTE() {
+ uint32_t mte_regnum = m_dynamic_reg_infos.size();
+ m_mte_regnum_collection.push_back(mte_regnum);
+ m_dynamic_reg_infos.push_back(g_register_infos_mte[0]);
+ m_dynamic_reg_infos[mte_regnum].byte_offset =
+ m_dynamic_reg_infos[mte_regnum - 1].byte_offset +
+ m_dynamic_reg_infos[mte_regnum - 1].byte_size;
+ m_dynamic_reg_infos[mte_regnum].kinds[lldb::eRegisterKindLLDB] = mte_regnum;
+
+ m_per_regset_regnum_range[m_register_set_count] =
+ std::make_pair(mte_regnum, mte_regnum + 1);
+ m_dynamic_reg_sets.push_back(g_reg_set_mte_arm64);
+ m_dynamic_reg_sets.back().registers = m_mte_regnum_collection.data();
+}
+
+uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) {
// sve_vq contains SVE Quad vector length in context of AArch64 SVE.
// SVE register infos if enabled cannot be disabled by selecting sve_vq = 0.
// Also if an invalid or previously set vector length is passed to this
@@ -266,28 +321,15 @@ RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
m_vector_reg_vq = sve_vq;
- if (sve_vq == eVectorQuadwordAArch64) {
- m_register_info_count =
- static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
- sizeof(g_register_infos_arm64_le[0]));
- m_register_info_p = g_register_infos_arm64_le;
-
+ if (sve_vq == eVectorQuadwordAArch64)
return m_vector_reg_vq;
- }
-
- m_register_info_count =
- static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) /
- sizeof(g_register_infos_arm64_sve_le[0]));
-
std::vector<lldb_private::RegisterInfo> &reg_info_ref =
m_per_vq_reg_infos[sve_vq];
if (reg_info_ref.empty()) {
- reg_info_ref = llvm::makeArrayRef(g_register_infos_arm64_sve_le,
- m_register_info_count);
+ reg_info_ref = llvm::makeArrayRef(m_register_info_p, m_register_info_count);
uint32_t offset = SVE_REGS_DEFAULT_OFFSET_LINUX;
-
reg_info_ref[fpu_fpsr].byte_offset = offset;
reg_info_ref[fpu_fpcr].byte_offset = offset + 4;
reg_info_ref[sve_vg].byte_offset = offset + 8;
@@ -316,13 +358,25 @@ RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
offset += reg_info_ref[it].byte_size;
}
+ for (uint32_t it = sve_ffr + 1; it < m_register_info_count; it++) {
+ reg_info_ref[it].byte_offset = offset;
+ offset += reg_info_ref[it].byte_size;
+ }
+
m_per_vq_reg_infos[sve_vq] = reg_info_ref;
}
- m_register_info_p = reg_info_ref.data();
+ m_register_info_p = m_per_vq_reg_infos[sve_vq].data();
return m_vector_reg_vq;
}
+bool RegisterInfoPOSIX_arm64::IsSVEReg(unsigned reg) const {
+ if (m_vector_reg_vq > eVectorQuadwordAArch64)
+ return (sve_vg <= reg && reg <= sve_ffr);
+ else
+ return false;
+}
+
bool RegisterInfoPOSIX_arm64::IsSVEZReg(unsigned reg) const {
return (sve_z0 <= reg && reg <= sve_z31);
}
@@ -335,6 +389,18 @@ bool RegisterInfoPOSIX_arm64::IsSVERegVG(unsigned reg) const {
return sve_vg == reg;
}
+bool RegisterInfoPOSIX_arm64::IsPAuthReg(unsigned reg) const {
+ return std::find(pauth_regnum_collection.begin(),
+ pauth_regnum_collection.end(),
+ reg) != pauth_regnum_collection.end();
+}
+
+bool RegisterInfoPOSIX_arm64::IsMTEReg(unsigned reg) const {
+ return std::find(m_mte_regnum_collection.begin(),
+ m_mte_regnum_collection.end(),
+ reg) != m_mte_regnum_collection.end();
+}
+
uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; }
uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; }
@@ -344,3 +410,11 @@ uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPCR() const { return fpu_fpcr; }
uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPSR() const { return fpu_fpsr; }
uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetPAuthOffset() const {
+ return m_register_info_p[pauth_regnum_collection[0]].byte_offset;
+}
+
+uint32_t RegisterInfoPOSIX_arm64::GetMTEOffset() const {
+ return m_register_info_p[m_mte_regnum_collection[0]].byte_offset;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index 2929f2009dd9..ba873ba4436b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -11,6 +11,7 @@
#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/Flags.h"
#include "lldb/lldb-private.h"
#include <map>
@@ -19,7 +20,16 @@ enum class SVEState { Unknown, Disabled, FPSIMD, Full };
class RegisterInfoPOSIX_arm64
: public lldb_private::RegisterInfoAndSetInterface {
public:
- enum { GPRegSet = 0, FPRegSet, SVERegSet };
+ enum { GPRegSet = 0, FPRegSet };
+
+ // AArch64 register set mask value
+ enum {
+ eRegsetMaskDefault = 0,
+ eRegsetMaskSVE = 1,
+ eRegsetMaskPAuth = 2,
+ eRegsetMaskMTE = 4,
+ eRegsetMaskDynamic = ~1,
+ };
// AArch64 Register set FP/SIMD feature configuration
enum {
@@ -68,7 +78,8 @@ public:
uint64_t mdscr_el1;
};
- RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch);
+ RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch,
+ lldb_private::Flags opt_regsets);
size_t GetGPRSize() const override;
@@ -85,7 +96,11 @@ public:
size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
- uint32_t ConfigureVectorRegisterInfos(uint32_t sve_vq);
+ void AddRegSetPAuth();
+
+ void AddRegSetMTE();
+
+ uint32_t ConfigureVectorLength(uint32_t sve_vq);
bool VectorSizeIsValid(uint32_t vq) {
if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax)
@@ -93,17 +108,23 @@ public:
return false;
}
- bool IsSVEEnabled() const { return m_vector_reg_vq > eVectorQuadwordAArch64; }
+ bool IsSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
+ bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
+ bool IsSVEReg(unsigned reg) const;
bool IsSVEZReg(unsigned reg) const;
bool IsSVEPReg(unsigned reg) const;
bool IsSVERegVG(unsigned reg) const;
+ bool IsPAuthReg(unsigned reg) const;
+ bool IsMTEReg(unsigned reg) const;
uint32_t GetRegNumSVEZ0() const;
uint32_t GetRegNumSVEFFR() const;
uint32_t GetRegNumFPCR() const;
uint32_t GetRegNumFPSR() const;
uint32_t GetRegNumSVEVG() const;
+ uint32_t GetPAuthOffset() const;
+ uint32_t GetMTEOffset() const;
private:
typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>>
@@ -115,6 +136,21 @@ private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
+
+ const lldb_private::RegisterSet *m_register_set_p;
+ uint32_t m_register_set_count;
+
+ // Contains pair of [start, end] register numbers of a register set with start
+ // and end included.
+ std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range;
+
+ lldb_private::Flags m_opt_regsets;
+
+ std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos;
+ std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets;
+
+ std::vector<uint32_t> pauth_regnum_collection;
+ std::vector<uint32_t> m_mte_regnum_collection;
};
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
index 3461d38a3901..159fd2856443 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
@@ -7,7 +7,7 @@
//===---------------------------------------------------------------------===//
#include <cassert>
-#include <stddef.h>
+#include <cstddef>
#include <vector>
#include "lldb/lldb-defines.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h
index 74b9e3b2db32..4af0069eb6f3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h
@@ -8,7 +8,7 @@
#ifdef DECLARE_REGISTER_INFOS_ARM_STRUCT
-#include <stddef.h>
+#include <cstddef>
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index 4aee55e7afba..47cedc31bcd7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -8,7 +8,7 @@
#ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT
-#include <stddef.h>
+#include <cstddef>
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
@@ -470,6 +470,13 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
LLDB_INVALID_REGNUM, lldb_kind \
}
+// Generates register kinds array for registers with only lldb kind
+#define KIND_ALL_INVALID \
+ { \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM \
+ }
+
// Generates register kinds array for vector registers
#define GPR64_KIND(reg, generic_kind) MISC_KIND(reg, gpr, generic_kind)
#define VREG_KIND(reg) MISC_KIND(reg, fpu, LLDB_INVALID_REGNUM)
@@ -526,6 +533,13 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
nullptr, 0 \
}
+// Defines pointer authentication mask registers
+#define DEFINE_EXTENSION_REG(reg) \
+ { \
+ #reg, nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \
+ KIND_ALL_INVALID, nullptr, nullptr, nullptr, 0 \
+ }
+
static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
// DEFINE_GPR64(name, GENERIC KIND)
DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1),
@@ -772,7 +786,12 @@ static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
{DEFINE_DBG(wcr, 13)},
{DEFINE_DBG(wcr, 14)},
{DEFINE_DBG(wcr, 15)}
- // clang-format on
};
+// clang-format on
+static lldb_private::RegisterInfo g_register_infos_pauth[] = {
+ DEFINE_EXTENSION_REG(data_mask), DEFINE_EXTENSION_REG(code_mask)};
+
+static lldb_private::RegisterInfo g_register_infos_mte[] = {
+ DEFINE_EXTENSION_REG(mte_ctrl)};
#endif // DECLARE_REGISTER_INFOS_ARM64_STRUCT
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h
index 08201fd1191c..93f93d56fda2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -6,7 +6,7 @@
//
//===---------------------------------------------------------------------===//
-#include <stddef.h>
+#include <cstddef>
#include "lldb/Core/dwarf.h"
#include "llvm/Support/Compiler.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
index b6e218ea4414..b28b91810e48 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stddef.h>
+#include <cstddef>
#include "lldb/Core/dwarf.h"
#include "llvm/Support/Compiler.h"
@@ -15,37 +15,11 @@
#ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
// Computes the offset of the given GPR in the user data area.
-#ifdef LINUX_MIPS64
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, gpr) + \
- LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
-#else
#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname))
-#endif
-
-// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
-
-// Computes the offset of the given MSA in the extended data area.
-#define MSA_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, msa) + \
- LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
// Note that the size and offset will be updated by platform-specific classes.
-#ifdef LINUX_MIPS64
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3) \
- { \
- #reg, alt, sizeof(((GPR_linux_mips *) 0)->reg), \
- GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
- {kind1, kind2, kind3, ptrace_##reg##_mips, \
- gpr_##reg##_mips64 }, \
- NULL, NULL, NULL, 0 \
- }
-#else
#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
{ \
#reg, alt, sizeof(((GPR_freebsd_mips *) 0)->reg), \
@@ -54,63 +28,10 @@
gpr_##reg##_mips64 }, \
NULL, NULL, NULL, 0 \
}
-#endif
-
-#define DEFINE_GPR_INFO(reg, alt, kind1, kind2, kind3) \
- { \
- #reg, alt, sizeof(((GPR_linux_mips *) 0)->reg) / 2, \
- GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
- {kind1, kind2, kind3, ptrace_##reg##_mips, \
- gpr_##reg##_mips64 }, \
- NULL, NULL, NULL, 0 \
- }
-
-const uint8_t dwarf_opcode_mips64[] = {
- llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr};
-
-#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \
- { \
- #reg, alt, sizeof(((FPR_linux_mips *) 0)->reg), \
- FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \
- {kind1, kind2, kind3, ptrace_##reg##_mips, \
- fpr_##reg##_mips64 }, \
- NULL, NULL, dwarf_opcode_mips64, \
- sizeof(dwarf_opcode_mips64) \
- }
-
-#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3) \
- { \
- #reg, alt, sizeof(((FPR_linux_mips *) 0)->reg), \
- FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
- {kind1, kind2, kind3, ptrace_##reg##_mips, \
- fpr_##reg##_mips64 }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
- { \
- #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
- MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8, \
- {kind1, kind2, kind3, kind4, \
- msa_##reg##_mips64 }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
- { \
- #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
- MSA_OFFSET(reg), eEncodingUint, eFormatHex, \
- {kind1, kind2, kind3, kind4, \
- msa_##reg##_mips64 }, \
- NULL, NULL, NULL, 0 \
- }
static RegisterInfo g_register_infos_mips64[] = {
// General purpose registers. EH_Frame, DWARF,
// Generic, Process Plugin
-#ifndef LINUX_MIPS64
DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64,
@@ -191,231 +112,6 @@ static RegisterInfo g_register_infos_mips64[] = {
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-#else
- DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64,
- LLDB_REGNUM_GENERIC_ARG1),
- DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64,
- LLDB_REGNUM_GENERIC_ARG2),
- DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64,
- LLDB_REGNUM_GENERIC_ARG3),
- DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64,
- LLDB_REGNUM_GENERIC_ARG4),
- DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64,
- LLDB_REGNUM_GENERIC_ARG5),
- DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64,
- LLDB_REGNUM_GENERIC_ARG6),
- DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64,
- LLDB_REGNUM_GENERIC_ARG7),
- DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64,
- LLDB_REGNUM_GENERIC_ARG8),
- DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64,
- LLDB_REGNUM_GENERIC_SP),
- DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64,
- LLDB_REGNUM_GENERIC_FP),
- DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64,
- LLDB_REGNUM_GENERIC_RA),
- DEFINE_GPR_INFO(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64,
- LLDB_REGNUM_GENERIC_FLAGS),
- DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR_INFO(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64,
- LLDB_REGNUM_GENERIC_PC),
- DEFINE_GPR_INFO(config5, nullptr, dwarf_config5_mips64,
- dwarf_config5_mips64, LLDB_INVALID_REGNUM),
- DEFINE_FPR(f0, nullptr, dwarf_f0_mips64, dwarf_f0_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f1, nullptr, dwarf_f1_mips64, dwarf_f1_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f2, nullptr, dwarf_f2_mips64, dwarf_f2_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f3, nullptr, dwarf_f3_mips64, dwarf_f3_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f4, nullptr, dwarf_f4_mips64, dwarf_f4_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f5, nullptr, dwarf_f5_mips64, dwarf_f5_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f6, nullptr, dwarf_f6_mips64, dwarf_f6_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f7, nullptr, dwarf_f7_mips64, dwarf_f7_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f8, nullptr, dwarf_f8_mips64, dwarf_f8_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f9, nullptr, dwarf_f9_mips64, dwarf_f9_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f10, nullptr, dwarf_f10_mips64, dwarf_f10_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f11, nullptr, dwarf_f11_mips64, dwarf_f11_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f12, nullptr, dwarf_f12_mips64, dwarf_f12_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f13, nullptr, dwarf_f13_mips64, dwarf_f13_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f14, nullptr, dwarf_f14_mips64, dwarf_f14_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f15, nullptr, dwarf_f15_mips64, dwarf_f15_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f16, nullptr, dwarf_f16_mips64, dwarf_f16_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f17, nullptr, dwarf_f17_mips64, dwarf_f17_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f18, nullptr, dwarf_f18_mips64, dwarf_f18_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f19, nullptr, dwarf_f19_mips64, dwarf_f19_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f20, nullptr, dwarf_f20_mips64, dwarf_f20_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f21, nullptr, dwarf_f21_mips64, dwarf_f21_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f22, nullptr, dwarf_f22_mips64, dwarf_f22_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f23, nullptr, dwarf_f23_mips64, dwarf_f23_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f24, nullptr, dwarf_f24_mips64, dwarf_f24_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f25, nullptr, dwarf_f25_mips64, dwarf_f25_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f26, nullptr, dwarf_f26_mips64, dwarf_f26_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f27, nullptr, dwarf_f27_mips64, dwarf_f27_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f28, nullptr, dwarf_f28_mips64, dwarf_f28_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f29, nullptr, dwarf_f29_mips64, dwarf_f29_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f30, nullptr, dwarf_f30_mips64, dwarf_f30_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR(f31, nullptr, dwarf_f31_mips64, dwarf_f31_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64,
- LLDB_INVALID_REGNUM),
- DEFINE_FPR_INFO(config5, nullptr, dwarf_config5_mips64,
- dwarf_config5_mips64, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w0, nullptr, dwarf_w0_mips64, dwarf_w0_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w1, nullptr, dwarf_w1_mips64, dwarf_w1_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w2, nullptr, dwarf_w2_mips64, dwarf_w2_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w3, nullptr, dwarf_w3_mips64, dwarf_w3_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w4, nullptr, dwarf_w4_mips64, dwarf_w4_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w5, nullptr, dwarf_w5_mips64, dwarf_w5_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w6, nullptr, dwarf_w6_mips64, dwarf_w6_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w7, nullptr, dwarf_w7_mips64, dwarf_w7_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w8, nullptr, dwarf_w8_mips64, dwarf_w8_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w9, nullptr, dwarf_w9_mips64, dwarf_w9_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w10, nullptr, dwarf_w10_mips64, dwarf_w10_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w11, nullptr, dwarf_w11_mips64, dwarf_w11_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w12, nullptr, dwarf_w12_mips64, dwarf_w12_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w13, nullptr, dwarf_w13_mips64, dwarf_w13_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w14, nullptr, dwarf_w14_mips64, dwarf_w14_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w15, nullptr, dwarf_w15_mips64, dwarf_w15_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w16, nullptr, dwarf_w16_mips64, dwarf_w16_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w17, nullptr, dwarf_w17_mips64, dwarf_w17_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w18, nullptr, dwarf_w18_mips64, dwarf_w18_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w19, nullptr, dwarf_w19_mips64, dwarf_w19_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w20, nullptr, dwarf_w10_mips64, dwarf_w20_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w21, nullptr, dwarf_w21_mips64, dwarf_w21_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w22, nullptr, dwarf_w22_mips64, dwarf_w22_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w23, nullptr, dwarf_w23_mips64, dwarf_w23_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w24, nullptr, dwarf_w24_mips64, dwarf_w24_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w25, nullptr, dwarf_w25_mips64, dwarf_w25_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w26, nullptr, dwarf_w26_mips64, dwarf_w26_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w27, nullptr, dwarf_w27_mips64, dwarf_w27_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w28, nullptr, dwarf_w28_mips64, dwarf_w28_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w29, nullptr, dwarf_w29_mips64, dwarf_w29_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w30, nullptr, dwarf_w30_mips64, dwarf_w30_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA(w31, nullptr, dwarf_w31_mips64, dwarf_w31_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA_INFO(mcsr, nullptr, dwarf_mcsr_mips64, dwarf_mcsr_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA_INFO(mir, nullptr, dwarf_mir_mips64, dwarf_mir_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_MSA_INFO(config5, nullptr, dwarf_config5_mips64,
- dwarf_config5_mips64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM)
-#endif
};
static_assert((sizeof(g_register_infos_mips64) /
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 90863dfdb090..04b4171b6722 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -6,7 +6,7 @@
//
//===---------------------------------------------------------------------===//
-#include <stddef.h>
+#include <cstddef>
// Computes the offset of the given GPR in the user data area.
#define GPR_OFFSET(regname) (offsetof(GPR, regname))
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
index 1086d3db0b06..059dba45f9bb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
@@ -8,7 +8,7 @@
#ifdef DECLARE_REGISTER_INFOS_PPC64_STRUCT
-#include <stddef.h>
+#include <cstddef>
// Computes the offset of the given GPR_PPC64 in the user data area.
#define GPR_PPC64_OFFSET(regname) (offsetof(GPR_PPC64, regname))
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
index 0b099a53d875..9937da2f3050 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
@@ -8,7 +8,7 @@
#ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-#include <stddef.h>
+#include <cstddef>
// Computes the offset of the given GPR in the user data area.
#define GPR_OFFSET(regname) (offsetof(GPR, regname))
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h
index 11344ff8ee79..d1df7c606207 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stddef.h>
+#include <cstddef>
#include "llvm/Support/Compiler.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 2d8e8ef21612..85785a20354d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -509,7 +509,7 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
// operating system thread ID, so we can't make any assumptions about
// the thread ID so we must always report the breakpoint regardless
// of the thread.
- if (bp_site_sp->ValidForThisThread(&thread) ||
+ if (bp_site_sp->ValidForThisThread(thread) ||
thread.GetProcess()->GetOperatingSystem() != nullptr)
return StopInfo::CreateStopReasonWithBreakpointSiteID(
thread, bp_site_sp->GetID());
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
deleted file mode 100644
index 348af27d2809..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
+++ /dev/null
@@ -1,360 +0,0 @@
-//===-- lldb-mips-linux-register-enums.h -------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
-
-namespace lldb_private {
-// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
-
-// Internal codes for all mips registers.
-enum {
- k_first_gpr_mips,
- gpr_zero_mips = k_first_gpr_mips,
- gpr_r1_mips,
- gpr_r2_mips,
- gpr_r3_mips,
- gpr_r4_mips,
- gpr_r5_mips,
- gpr_r6_mips,
- gpr_r7_mips,
- gpr_r8_mips,
- gpr_r9_mips,
- gpr_r10_mips,
- gpr_r11_mips,
- gpr_r12_mips,
- gpr_r13_mips,
- gpr_r14_mips,
- gpr_r15_mips,
- gpr_r16_mips,
- gpr_r17_mips,
- gpr_r18_mips,
- gpr_r19_mips,
- gpr_r20_mips,
- gpr_r21_mips,
- gpr_r22_mips,
- gpr_r23_mips,
- gpr_r24_mips,
- gpr_r25_mips,
- gpr_r26_mips,
- gpr_r27_mips,
- gpr_gp_mips,
- gpr_sp_mips,
- gpr_r30_mips,
- gpr_ra_mips,
- gpr_sr_mips,
- gpr_mullo_mips,
- gpr_mulhi_mips,
- gpr_badvaddr_mips,
- gpr_cause_mips,
- gpr_pc_mips,
- gpr_config5_mips,
-
- k_last_gpr_mips = gpr_config5_mips,
-
- k_first_fpr_mips,
- fpr_f0_mips = k_first_fpr_mips,
- fpr_f1_mips,
- fpr_f2_mips,
- fpr_f3_mips,
- fpr_f4_mips,
- fpr_f5_mips,
- fpr_f6_mips,
- fpr_f7_mips,
- fpr_f8_mips,
- fpr_f9_mips,
- fpr_f10_mips,
- fpr_f11_mips,
- fpr_f12_mips,
- fpr_f13_mips,
- fpr_f14_mips,
- fpr_f15_mips,
- fpr_f16_mips,
- fpr_f17_mips,
- fpr_f18_mips,
- fpr_f19_mips,
- fpr_f20_mips,
- fpr_f21_mips,
- fpr_f22_mips,
- fpr_f23_mips,
- fpr_f24_mips,
- fpr_f25_mips,
- fpr_f26_mips,
- fpr_f27_mips,
- fpr_f28_mips,
- fpr_f29_mips,
- fpr_f30_mips,
- fpr_f31_mips,
- fpr_fcsr_mips,
- fpr_fir_mips,
- fpr_config5_mips,
- k_last_fpr_mips = fpr_config5_mips,
-
- k_first_msa_mips,
- msa_w0_mips = k_first_msa_mips,
- msa_w1_mips,
- msa_w2_mips,
- msa_w3_mips,
- msa_w4_mips,
- msa_w5_mips,
- msa_w6_mips,
- msa_w7_mips,
- msa_w8_mips,
- msa_w9_mips,
- msa_w10_mips,
- msa_w11_mips,
- msa_w12_mips,
- msa_w13_mips,
- msa_w14_mips,
- msa_w15_mips,
- msa_w16_mips,
- msa_w17_mips,
- msa_w18_mips,
- msa_w19_mips,
- msa_w20_mips,
- msa_w21_mips,
- msa_w22_mips,
- msa_w23_mips,
- msa_w24_mips,
- msa_w25_mips,
- msa_w26_mips,
- msa_w27_mips,
- msa_w28_mips,
- msa_w29_mips,
- msa_w30_mips,
- msa_w31_mips,
- msa_fcsr_mips,
- msa_fir_mips,
- msa_mcsr_mips,
- msa_mir_mips,
- msa_config5_mips,
- k_last_msa_mips = msa_config5_mips,
-
- k_num_registers_mips,
-
- k_num_gpr_registers_mips = k_last_gpr_mips - k_first_gpr_mips + 1,
- k_num_fpr_registers_mips = k_last_fpr_mips - k_first_fpr_mips + 1,
- k_num_msa_registers_mips = k_last_msa_mips - k_first_msa_mips + 1,
- k_num_user_registers_mips = k_num_gpr_registers_mips +
- k_num_fpr_registers_mips +
- k_num_msa_registers_mips
-};
-
-// Internal codes for all mips64 registers.
-enum {
- k_first_gpr_mips64,
- gpr_zero_mips64 = k_first_gpr_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_config5_mips64,
- k_last_gpr_mips64 = gpr_config5_mips64,
-
- k_first_fpr_mips64,
- fpr_f0_mips64 = k_first_fpr_mips64,
- fpr_f1_mips64,
- fpr_f2_mips64,
- fpr_f3_mips64,
- fpr_f4_mips64,
- fpr_f5_mips64,
- fpr_f6_mips64,
- fpr_f7_mips64,
- fpr_f8_mips64,
- fpr_f9_mips64,
- fpr_f10_mips64,
- fpr_f11_mips64,
- fpr_f12_mips64,
- fpr_f13_mips64,
- fpr_f14_mips64,
- fpr_f15_mips64,
- fpr_f16_mips64,
- fpr_f17_mips64,
- fpr_f18_mips64,
- fpr_f19_mips64,
- fpr_f20_mips64,
- fpr_f21_mips64,
- fpr_f22_mips64,
- fpr_f23_mips64,
- fpr_f24_mips64,
- fpr_f25_mips64,
- fpr_f26_mips64,
- fpr_f27_mips64,
- fpr_f28_mips64,
- fpr_f29_mips64,
- fpr_f30_mips64,
- fpr_f31_mips64,
- fpr_fcsr_mips64,
- fpr_fir_mips64,
- fpr_config5_mips64,
- k_last_fpr_mips64 = fpr_config5_mips64,
-
- k_first_msa_mips64,
- msa_w0_mips64 = k_first_msa_mips64,
- msa_w1_mips64,
- msa_w2_mips64,
- msa_w3_mips64,
- msa_w4_mips64,
- msa_w5_mips64,
- msa_w6_mips64,
- msa_w7_mips64,
- msa_w8_mips64,
- msa_w9_mips64,
- msa_w10_mips64,
- msa_w11_mips64,
- msa_w12_mips64,
- msa_w13_mips64,
- msa_w14_mips64,
- msa_w15_mips64,
- msa_w16_mips64,
- msa_w17_mips64,
- msa_w18_mips64,
- msa_w19_mips64,
- msa_w20_mips64,
- msa_w21_mips64,
- msa_w22_mips64,
- msa_w23_mips64,
- msa_w24_mips64,
- msa_w25_mips64,
- msa_w26_mips64,
- msa_w27_mips64,
- msa_w28_mips64,
- msa_w29_mips64,
- msa_w30_mips64,
- msa_w31_mips64,
- msa_fcsr_mips64,
- msa_fir_mips64,
- msa_mcsr_mips64,
- msa_mir_mips64,
- msa_config5_mips64,
- k_last_msa_mips64 = msa_config5_mips64,
-
- k_num_registers_mips64,
-
- k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1,
- k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1,
- k_num_msa_registers_mips64 = k_last_msa_mips64 - k_first_msa_mips64 + 1,
- k_num_user_registers_mips64 = k_num_gpr_registers_mips64 +
- k_num_fpr_registers_mips64 +
- k_num_msa_registers_mips64
-};
-
-// Register no. for RegisterKind = eRegisterKindProcessPlugin
-// The ptrace request PTRACE_PEEKUSER/PTRACE_POKEUSER used this number
-enum {
- ptrace_zero_mips,
- ptrace_r1_mips,
- ptrace_r2_mips,
- ptrace_r3_mips,
- ptrace_r4_mips,
- ptrace_r5_mips,
- ptrace_r6_mips,
- ptrace_r7_mips,
- ptrace_r8_mips,
- ptrace_r9_mips,
- ptrace_r10_mips,
- ptrace_r11_mips,
- ptrace_r12_mips,
- ptrace_r13_mips,
- ptrace_r14_mips,
- ptrace_r15_mips,
- ptrace_r16_mips,
- ptrace_r17_mips,
- ptrace_r18_mips,
- ptrace_r19_mips,
- ptrace_r20_mips,
- ptrace_r21_mips,
- ptrace_r22_mips,
- ptrace_r23_mips,
- ptrace_r24_mips,
- ptrace_r25_mips,
- ptrace_r26_mips,
- ptrace_r27_mips,
- ptrace_gp_mips,
- ptrace_sp_mips,
- ptrace_r30_mips,
- ptrace_ra_mips,
- ptrace_f0_mips,
- ptrace_f1_mips,
- ptrace_f2_mips,
- ptrace_f3_mips,
- ptrace_f4_mips,
- ptrace_f5_mips,
- ptrace_f6_mips,
- ptrace_f7_mips,
- ptrace_f8_mips,
- ptrace_f9_mips,
- ptrace_f10_mips,
- ptrace_f11_mips,
- ptrace_f12_mips,
- ptrace_f13_mips,
- ptrace_f14_mips,
- ptrace_f15_mips,
- ptrace_f16_mips,
- ptrace_f17_mips,
- ptrace_f18_mips,
- ptrace_f19_mips,
- ptrace_f20_mips,
- ptrace_f21_mips,
- ptrace_f22_mips,
- ptrace_f23_mips,
- ptrace_f24_mips,
- ptrace_f25_mips,
- ptrace_f26_mips,
- ptrace_f27_mips,
- ptrace_f28_mips,
- ptrace_f29_mips,
- ptrace_f30_mips,
- ptrace_f31_mips,
- ptrace_pc_mips,
- ptrace_cause_mips,
- ptrace_badvaddr_mips,
- ptrace_mulhi_mips,
- ptrace_mullo_mips,
- ptrace_fcsr_mips,
- ptrace_fir_mips,
- ptrace_sr_mips,
- ptrace_config5_mips
-};
-}
-
-#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index ae19367ca3ae..12bc7390c729 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stdlib.h>
+#include <cstdlib>
#include <memory>
#include <mutex>
@@ -353,7 +353,6 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
const lldb::addr_t file_end = address_range->data.GetRangeEnd();
size_t bytes_to_read = size; // Number of bytes to read from the core file
size_t bytes_copied = 0; // Number of bytes actually read from the core file
- size_t zero_fill_size = 0; // Padding
lldb::addr_t bytes_left =
0; // Number of bytes available in the core file from the given address
@@ -367,24 +366,15 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
if (file_end > file_start + offset)
bytes_left = file_end - (file_start + offset);
- // Figure out how many bytes we need to zero-fill if we are reading more
- // bytes than available in the on-disk segment
- if (bytes_to_read > bytes_left) {
- zero_fill_size = bytes_to_read - bytes_left;
+ if (bytes_to_read > bytes_left)
bytes_to_read = bytes_left;
- }
// If there is data available on the core file read it
if (bytes_to_read)
bytes_copied =
core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
- assert(zero_fill_size <= size);
- // Pad remaining bytes
- if (zero_fill_size)
- memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
-
- return bytes_copied + zero_fill_size;
+ return bytes_copied;
}
void ProcessElfCore::Clear() {
@@ -414,12 +404,8 @@ lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
static void ParseFreeBSDPrStatus(ThreadData &thread_data,
const DataExtractor &data,
- const ArchSpec &arch) {
+ bool lp64) {
lldb::offset_t offset = 0;
- bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
- arch.GetMachine() == llvm::Triple::mips64 ||
- arch.GetMachine() == llvm::Triple::ppc64 ||
- arch.GetMachine() == llvm::Triple::x86_64);
int pr_version = data.GetU32(&offset);
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -443,6 +429,27 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data,
thread_data.gpregset = DataExtractor(data, offset, len);
}
+// Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details.
+static void ParseFreeBSDPrPsInfo(ProcessElfCore &process,
+ const DataExtractor &data,
+ bool lp64) {
+ lldb::offset_t offset = 0;
+ int pr_version = data.GetU32(&offset);
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ if (pr_version > 1)
+ LLDB_LOGF(log, "FreeBSD PRPSINFO unexpected version %d", pr_version);
+ }
+
+ // Skip pr_psinfosz, pr_fname, pr_psargs
+ offset += 108;
+ if (lp64)
+ offset += 4;
+
+ process.SetID(data.GetU32(&offset)); // pr_pid
+}
+
static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data,
uint32_t &cpi_nlwps,
uint32_t &cpi_signo,
@@ -522,6 +529,11 @@ ProcessElfCore::parseSegment(const DataExtractor &segment) {
}
llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
+ ArchSpec arch = GetArchitecture();
+ bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
+ arch.GetMachine() == llvm::Triple::mips64 ||
+ arch.GetMachine() == llvm::Triple::ppc64 ||
+ arch.GetMachine() == llvm::Triple::x86_64);
bool have_prstatus = false;
bool have_prpsinfo = false;
ThreadData thread_data;
@@ -542,10 +554,11 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
switch (note.info.n_type) {
case ELF::NT_PRSTATUS:
have_prstatus = true;
- ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
+ ParseFreeBSDPrStatus(thread_data, note.data, lp64);
break;
case ELF::NT_PRPSINFO:
have_prpsinfo = true;
+ ParseFreeBSDPrPsInfo(*this, note.data, lp64);
break;
case ELF::NT_FREEBSD_THRMISC: {
lldb::offset_t offset = 0;
@@ -651,6 +664,32 @@ llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
thread_data.notes.push_back(note);
}
} break;
+ case llvm::Triple::x86: {
+ // Assume order PT_GETREGS, PT_GETFPREGS
+ if (note.info.n_type == NETBSD::I386::NT_REGS) {
+ // If this is the next thread, push the previous one first.
+ if (had_nt_regs) {
+ m_thread_data.push_back(thread_data);
+ thread_data = ThreadData();
+ had_nt_regs = false;
+ }
+
+ thread_data.gpregset = note.data;
+ thread_data.tid = tid;
+ if (thread_data.gpregset.GetByteSize() == 0)
+ return llvm::make_error<llvm::StringError>(
+ "Could not find general purpose registers note in core file.",
+ llvm::inconvertibleErrorCode());
+ had_nt_regs = true;
+ } else if (note.info.n_type == NETBSD::I386::NT_FPREGS) {
+ if (!had_nt_regs || tid != thread_data.tid)
+ return llvm::make_error<llvm::StringError>(
+ "Error parsing NetBSD core(5) notes: Unexpected order "
+ "of NOTEs PT_GETFPREG before PT_GETREG",
+ llvm::inconvertibleErrorCode());
+ thread_data.notes.push_back(note);
+ }
+ } break;
case llvm::Triple::x86_64: {
// Assume order PT_GETREGS, PT_GETFPREGS
if (note.info.n_type == NETBSD::AMD64::NT_REGS) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 2f71f175a00d..f0aee04b5f62 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -25,7 +25,7 @@ RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(
m_gpr.SetByteOrder(gpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() {}
+RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() = default;
bool RegisterContextCorePOSIX_arm::ReadGPR() { return true; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 129a887a550c..e56aa88b57d9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -17,26 +17,52 @@
using namespace lldb_private;
+std::unique_ptr<RegisterContextCorePOSIX_arm64>
+RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
+ const DataExtractor &gpregset,
+ llvm::ArrayRef<CoreNote> notes) {
+ Flags opt_regsets = RegisterInfoPOSIX_arm64::eRegsetMaskDefault;
+
+ DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
+ if (sve_data.GetByteSize() > sizeof(sve::user_sve_header))
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
+
+ // Pointer Authentication register set data is based on struct
+ // user_pac_mask declared in ptrace.h. See reference implementation
+ // in Linux kernel source at arch/arm64/include/uapi/asm/ptrace.h.
+ DataExtractor pac_data = getRegset(notes, arch.GetTriple(), AARCH64_PAC_Desc);
+ if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2)
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
+
+ auto register_info_up =
+ std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
+ return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
+ new RegisterContextCorePOSIX_arm64(thread, std::move(register_info_up),
+ gpregset, notes));
+}
+
RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
- m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
- gpregset.GetByteSize());
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
+ m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
+ gpregset.GetByteSize()));
+ m_gpr_data.SetByteOrder(gpregset.GetByteOrder());
- m_fpregset = getRegset(
- notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc);
+ const llvm::Triple &target_triple =
+ m_register_info_up->GetTargetArchitecture().GetTriple();
+ m_fpr_data = getRegset(notes, target_triple, FPR_Desc);
- m_sveregset =
- getRegset(notes, m_register_info_up->GetTargetArchitecture().GetTriple(),
- AARCH64_SVE_Desc);
+ if (m_register_info_up->IsSVEEnabled())
+ m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc);
+
+ if (m_register_info_up->IsPAuthEnabled())
+ m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
ConfigureRegisterContext();
}
-RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {}
+RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() = default;
bool RegisterContextCorePOSIX_arm64::ReadGPR() { return true; }
@@ -53,16 +79,16 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() {
}
const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) {
- return m_sveregset.GetDataStart() + offset;
+ return m_sve_data.GetDataStart() + offset;
}
void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
- if (m_sveregset.GetByteSize() > sizeof(sve::user_sve_header)) {
+ if (m_sve_data.GetByteSize() > sizeof(sve::user_sve_header)) {
uint64_t sve_header_field_offset = 8;
- m_sve_vector_length = m_sveregset.GetU16(&sve_header_field_offset);
+ m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset);
sve_header_field_offset = 12;
uint16_t sve_header_flags_field =
- m_sveregset.GetU16(&sve_header_field_offset);
+ m_sve_data.GetU16(&sve_header_field_offset);
if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
sve::ptrace_regs_fpsimd)
m_sve_state = SVEState::FPSIMD;
@@ -70,15 +96,16 @@ void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
sve::ptrace_regs_sve)
m_sve_state = SVEState::Full;
- if (sve::vl_valid(m_sve_vector_length))
- m_register_info_up->ConfigureVectorRegisterInfos(
- sve::vq_from_vl(m_sve_vector_length));
- else {
+ if (!sve::vl_valid(m_sve_vector_length)) {
m_sve_state = SVEState::Disabled;
m_sve_vector_length = 0;
}
} else
m_sve_state = SVEState::Disabled;
+
+ if (m_sve_state != SVEState::Disabled)
+ m_register_info_up->ConfigureVectorLength(
+ sve::vq_from_vl(m_sve_vector_length));
}
uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset(
@@ -104,7 +131,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
offset = reg_info->byte_offset;
if (offset + reg_info->byte_size <= GetGPRSize()) {
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ uint64_t v = m_gpr_data.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size) {
value = v;
return true;
@@ -119,8 +146,8 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
if (m_sve_state == SVEState::Disabled) {
// SVE is disabled take legacy route for FPU register access
offset -= GetGPRSize();
- if (offset < m_fpregset.GetByteSize()) {
- value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
+ if (offset < m_fpr_data.GetByteSize()) {
+ value.SetFromMemoryData(reg_info, m_fpr_data.GetDataStart() + offset,
reg_info->byte_size, lldb::eByteOrderLittle,
error);
return error.Success();
@@ -152,7 +179,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
}
assert(sve_reg_num != LLDB_INVALID_REGNUM);
- assert(offset < m_sveregset.GetByteSize());
+ assert(offset < m_sve_data.GetByteSize());
value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
reg_info->byte_size, lldb::eByteOrderLittle,
error);
@@ -174,7 +201,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
if (IsSVEZ(reg)) {
byte_size = 16;
offset = CalculateSVEOffset(reg_info);
- assert(offset < m_sveregset.GetByteSize());
+ assert(offset < m_sve_data.GetByteSize());
src = GetSVEBuffer(offset);
}
value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle,
@@ -182,7 +209,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
} break;
case SVEState::Full:
offset = CalculateSVEOffset(reg_info);
- assert(offset < m_sveregset.GetByteSize());
+ assert(offset < m_sve_data.GetByteSize());
value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
reg_info->byte_size, lldb::eByteOrderLittle,
error);
@@ -191,6 +218,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
default:
return false;
}
+ } else if (IsPAuth(reg)) {
+ offset = reg_info->byte_offset - m_register_info_up->GetPAuthOffset();
+ assert(offset < m_pac_data.GetByteSize());
+ value.SetFromMemoryData(reg_info, m_pac_data.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
} else
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index a4fdc4f14328..3988e3539b89 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -18,11 +18,10 @@
class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
public:
- RegisterContextCorePOSIX_arm64(
- lldb_private::Thread &thread,
- std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
- const lldb_private::DataExtractor &gpregset,
- llvm::ArrayRef<lldb_private::CoreNote> notes);
+ static std::unique_ptr<RegisterContextCorePOSIX_arm64>
+ Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch,
+ const lldb_private::DataExtractor &gpregset,
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_arm64() override;
@@ -39,6 +38,12 @@ public:
bool HardwareSingleStep(bool enable) override;
protected:
+ RegisterContextCorePOSIX_arm64(
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
+ const lldb_private::DataExtractor &gpregset,
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
+
bool ReadGPR() override;
bool ReadFPR() override;
@@ -48,10 +53,10 @@ protected:
bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
- lldb_private::DataExtractor m_fpregset;
- lldb_private::DataExtractor m_sveregset;
+ lldb_private::DataExtractor m_gpr_data;
+ lldb_private::DataExtractor m_fpr_data;
+ lldb_private::DataExtractor m_sve_data;
+ lldb_private::DataExtractor m_pac_data;
SVEState m_sve_state;
uint16_t m_sve_vector_length = 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index b5b83d899a44..5b1eb8b5437d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -32,7 +32,7 @@ RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(
m_fpr.SetByteOrder(fpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {}
+RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() = default;
bool RegisterContextCorePOSIX_mips64::ReadGPR() { return true; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index e15cd47cd7da..8380731692a3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -39,7 +39,7 @@ RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(
m_vec.SetByteOrder(vregset.GetByteOrder());
}
-RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() {}
+RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() = default;
bool RegisterContextCorePOSIX_powerpc::ReadGPR() { return true; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index c3aa92c9f86c..f1cd6897616d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -33,7 +33,7 @@ RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(
m_fpr.SetByteOrder(fpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() {}
+RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() = default;
bool RegisterContextCorePOSIX_s390x::ReadGPR() { return true; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index 25abd7ed54b7..f6a2fbdcc938 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -55,6 +55,10 @@ namespace AMD64 {
enum { NT_REGS = 33, NT_FPREGS = 35 };
}
+namespace I386 {
+enum { NT_REGS = 33, NT_FPREGS = 35 };
+}
+
} // namespace NETBSD
namespace OPENBSD {
@@ -96,6 +100,9 @@ DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes,
llvm::ArrayRef<RegsetDesc> RegsetDescs);
constexpr RegsetDesc FPR_Desc[] = {
+ // FreeBSD/i386 core NT_FPREGSET is x87 FSAVE result but the XSAVE dump
+ // starts with FXSAVE struct, so use that instead if available.
+ {llvm::Triple::FreeBSD, llvm::Triple::x86, llvm::ELF::NT_X86_XSTATE},
{llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
// In a i386 core file NT_FPREGSET is present, but it's not the result
// of the FXSAVE instruction like in 64 bit files.
@@ -103,6 +110,7 @@ constexpr RegsetDesc FPR_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG},
{llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
{llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS},
+ {llvm::Triple::NetBSD, llvm::Triple::x86, NETBSD::I386::NT_FPREGS},
{llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS},
{llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
};
@@ -111,6 +119,10 @@ constexpr RegsetDesc AARCH64_SVE_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE},
};
+constexpr RegsetDesc AARCH64_PAC_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
+};
+
constexpr RegsetDesc PPC_VMX_Desc[] = {
{llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
{llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 6c3ee9debc7c..5086cfaa6536 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -18,12 +18,11 @@
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
#ifdef LLDB_ENABLE_ALL
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#endif // LLDB_ENABLE_ALL
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
@@ -113,6 +112,9 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextNetBSD_i386(arch);
+ break;
case llvm::Triple::x86_64:
reg_interface = new RegisterContextNetBSD_x86_64(arch);
break;
@@ -126,14 +128,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
break;
- case llvm::Triple::mipsel:
- case llvm::Triple::mips:
- reg_interface = new RegisterContextLinux_mips(arch);
- break;
- case llvm::Triple::mips64el:
- case llvm::Triple::mips64:
- reg_interface = new RegisterContextLinux_mips64(arch);
- break;
case llvm::Triple::ppc64le:
reg_interface = new RegisterInfoPOSIX_ppc64le(arch);
break;
@@ -183,9 +177,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
- m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>(
- *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch),
- m_gpregset_data, m_notes);
+ m_thread_reg_ctx_sp = RegisterContextCorePOSIX_arm64::Create(
+ *this, arch, m_gpregset_data, m_notes);
break;
case llvm::Triple::arm:
m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>(
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index fdaa60e2df41..a4c71e864a76 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -20,7 +20,10 @@ using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
using namespace std::chrono;
-static const seconds kInterruptTimeout(5);
+// When we've sent a continue packet and are waiting for the target to stop,
+// we wake up the wait with this interval to make sure the stub hasn't gone
+// away while we were waiting.
+static const seconds kWakeupInterval(5);
/////////////////////////
// GDBRemoteClientBase //
@@ -35,7 +38,8 @@ GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
ContinueDelegate &delegate, const UnixSignals &signals,
- llvm::StringRef payload, StringExtractorGDBRemote &response) {
+ llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
+ StringExtractorGDBRemote &response) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
response.Clear();
@@ -48,16 +52,37 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
if (!cont_lock)
return eStateInvalid;
OnRunPacketSent(true);
-
+ // The main ReadPacket loop wakes up at computed_timeout intervals, just to
+ // check that the connection hasn't dropped. When we wake up we also check
+ // whether there is an interrupt request that has reached its endpoint.
+ // If we want a shorter interrupt timeout that kWakeupInterval, we need to
+ // choose the shorter interval for the wake up as well.
+ std::chrono::seconds computed_timeout = std::min(interrupt_timeout,
+ kWakeupInterval);
for (;;) {
- PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
+ PacketResult read_result = ReadPacket(response, computed_timeout, false);
+ // Reset the computed_timeout to the default value in case we are going
+ // round again.
+ computed_timeout = std::min(interrupt_timeout, kWakeupInterval);
switch (read_result) {
case PacketResult::ErrorReplyTimeout: {
std::lock_guard<std::mutex> lock(m_mutex);
- if (m_async_count == 0)
+ if (m_async_count == 0) {
continue;
- if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
+ }
+ auto cur_time = steady_clock::now();
+ if (cur_time >= m_interrupt_endpoint)
return eStateInvalid;
+ else {
+ // We woke up and found an interrupt is in flight, but we haven't
+ // exceeded the interrupt wait time. So reset the wait time to the
+ // time left till the interrupt timeout. But don't wait longer
+ // than our wakeup timeout.
+ auto new_wait = m_interrupt_endpoint - cur_time;
+ computed_timeout = std::min(kWakeupInterval,
+ std::chrono::duration_cast<std::chrono::seconds>(new_wait));
+ continue;
+ }
break;
}
case PacketResult::Success:
@@ -133,8 +158,9 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
}
}
-bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
- Lock lock(*this, true);
+bool GDBRemoteClientBase::SendAsyncSignal(
+ int signo, std::chrono::seconds interrupt_timeout) {
+ Lock lock(*this, interrupt_timeout);
if (!lock || !lock.DidInterrupt())
return false;
@@ -144,25 +170,26 @@ bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
return true;
}
-bool GDBRemoteClientBase::Interrupt() {
- Lock lock(*this, true);
+bool GDBRemoteClientBase::Interrupt(std::chrono::seconds interrupt_timeout) {
+ Lock lock(*this, interrupt_timeout);
if (!lock.DidInterrupt())
return false;
m_should_stop = true;
return true;
}
+
GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndWaitForResponse(
llvm::StringRef payload, StringExtractorGDBRemote &response,
- bool send_async) {
- Lock lock(*this, send_async);
+ std::chrono::seconds interrupt_timeout) {
+ Lock lock(*this, interrupt_timeout);
if (!lock) {
if (Log *log =
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
LLDB_LOGF(log,
"GDBRemoteClientBase::%s failed to get mutex, not sending "
- "packet '%.*s' (send_async=%d)",
- __FUNCTION__, int(payload.size()), payload.data(), send_async);
+ "packet '%.*s'",
+ __FUNCTION__, int(payload.size()), payload.data());
return PacketResult::ErrorSendFailed;
}
@@ -172,16 +199,16 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse(
GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
llvm::StringRef payload, StringExtractorGDBRemote &response,
- bool send_async,
+ std::chrono::seconds interrupt_timeout,
llvm::function_ref<void(llvm::StringRef)> output_callback) {
- Lock lock(*this, send_async);
+ Lock lock(*this, interrupt_timeout);
if (!lock) {
if (Log *log =
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
LLDB_LOGF(log,
"GDBRemoteClientBase::%s failed to get mutex, not sending "
- "packet '%.*s' (send_async=%d)",
- __FUNCTION__, int(payload.size()), payload.data(), send_async);
+ "packet '%.*s'",
+ __FUNCTION__, int(payload.size()), payload.data());
return PacketResult::ErrorSendFailed;
}
@@ -222,13 +249,14 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
return packet_result;
}
-bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
- StringExtractorGDBRemote &response) {
+bool GDBRemoteClientBase::SendvContPacket(
+ llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
+ StringExtractorGDBRemote &response) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
// we want to lock down packet sending while we continue
- Lock lock(*this, true);
+ Lock lock(*this, interrupt_timeout);
LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
@@ -336,18 +364,20 @@ GDBRemoteClientBase::ContinueLock::lock() {
// GDBRemoteClientBase::Lock //
///////////////////////////////
-GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
+GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm,
+ std::chrono::seconds interrupt_timeout)
: m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
- m_acquired(false), m_did_interrupt(false) {
- SyncWithContinueThread(interrupt);
+ m_interrupt_timeout(interrupt_timeout), m_acquired(false),
+ m_did_interrupt(false) {
+ SyncWithContinueThread();
if (m_acquired)
m_async_lock.lock();
}
-void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
+void GDBRemoteClientBase::Lock::SyncWithContinueThread() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
std::unique_lock<std::mutex> lock(m_comm.m_mutex);
- if (m_comm.m_is_running && !interrupt)
+ if (m_comm.m_is_running && m_interrupt_timeout == std::chrono::seconds(0))
return; // We were asked to avoid interrupting the sender. Lock is not
// acquired.
@@ -365,9 +395,9 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
"interrupt packet");
return;
}
+ m_comm.m_interrupt_endpoint = steady_clock::now() + m_interrupt_timeout;
if (log)
log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
- m_comm.m_interrupt_time = steady_clock::now();
}
m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; });
m_did_interrupt = true;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index cd9f6ebd7642..518b81318b6c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -33,29 +33,46 @@ public:
GDBRemoteClientBase(const char *comm_name, const char *listener_name);
- bool SendAsyncSignal(int signo);
+ bool SendAsyncSignal(int signo, std::chrono::seconds interrupt_timeout);
- bool Interrupt();
+ bool Interrupt(std::chrono::seconds interrupt_timeout);
lldb::StateType SendContinuePacketAndWaitForResponse(
ContinueDelegate &delegate, const UnixSignals &signals,
- llvm::StringRef payload, StringExtractorGDBRemote &response);
-
- PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
- StringExtractorGDBRemote &response,
- bool send_async);
+ llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
+ StringExtractorGDBRemote &response);
+
+ // If interrupt_timeout == 0 seconds, don't interrupt the target.
+ // Only send the packet if the target is stopped.
+ // If you want to use this mode, use the fact that the timeout is defaulted
+ // so it's clear from the call-site that you are using no-interrupt.
+ // If it is non-zero, interrupt the target if it is running, and
+ // send the packet.
+ // It the target doesn't respond within the given timeout, it returns
+ // ErrorReplyTimeout.
+ PacketResult SendPacketAndWaitForResponse(
+ llvm::StringRef payload, StringExtractorGDBRemote &response,
+ std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
PacketResult SendPacketAndReceiveResponseWithOutputSupport(
llvm::StringRef payload, StringExtractorGDBRemote &response,
- bool send_async,
+ std::chrono::seconds interrupt_timeout,
llvm::function_ref<void(llvm::StringRef)> output_callback);
bool SendvContPacket(llvm::StringRef payload,
+ std::chrono::seconds interrupt_timeout,
StringExtractorGDBRemote &response);
class Lock {
public:
- Lock(GDBRemoteClientBase &comm, bool interrupt);
+ // If interrupt_timeout == 0 seconds, only take the lock if the target is
+ // not running. If using this option, use the fact that the
+ // interrupt_timeout is defaulted so it will be obvious at the call site
+ // that you are choosing this mode. If it is non-zero, interrupt the target
+ // if it is running, waiting for the given timeout for the interrupt to
+ // succeed.
+ Lock(GDBRemoteClientBase &comm,
+ std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
~Lock();
explicit operator bool() { return m_acquired; }
@@ -67,10 +84,11 @@ public:
private:
std::unique_lock<std::recursive_mutex> m_async_lock;
GDBRemoteClientBase &m_comm;
+ std::chrono::seconds m_interrupt_timeout;
bool m_acquired;
bool m_did_interrupt;
- void SyncWithContinueThread(bool interrupt);
+ void SyncWithContinueThread();
};
protected:
@@ -109,7 +127,7 @@ private:
/// When was the interrupt packet sent. Used to make sure we time out if the
/// stub does not respond to interrupt requests.
- std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
+ std::chrono::time_point<std::chrono::steady_clock> m_interrupt_endpoint;
/// Number of threads interested in sending.
uint32_t m_async_count;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 4981345d6a18..013d407c0fc1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -8,9 +8,9 @@
#include "GDBRemoteCommunication.h"
+#include <climits>
+#include <cstring>
#include <future>
-#include <limits.h>
-#include <string.h>
#include <sys/stat.h>
#include "lldb/Core/StreamFile.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index d375a312ae2c..b16aed4f5c90 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -8,7 +8,7 @@
#include "GDBRemoteCommunicationClient.h"
-#include <math.h>
+#include <cmath>
#include <sys/stat.h>
#include <numeric>
@@ -16,6 +16,7 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/XML.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/MemoryRegionInfo.h"
@@ -55,40 +56,7 @@ llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,
// GDBRemoteCommunicationClient constructor
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
: GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
- m_supports_not_sending_acks(eLazyBoolCalculate),
- m_supports_thread_suffix(eLazyBoolCalculate),
- m_supports_threads_in_stop_reply(eLazyBoolCalculate),
- m_supports_vCont_all(eLazyBoolCalculate),
- m_supports_vCont_any(eLazyBoolCalculate),
- m_supports_vCont_c(eLazyBoolCalculate),
- m_supports_vCont_C(eLazyBoolCalculate),
- m_supports_vCont_s(eLazyBoolCalculate),
- m_supports_vCont_S(eLazyBoolCalculate),
- m_qHostInfo_is_valid(eLazyBoolCalculate),
- m_curr_pid_is_valid(eLazyBoolCalculate),
- m_qProcessInfo_is_valid(eLazyBoolCalculate),
- m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
- m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
- m_supports_memory_region_info(eLazyBoolCalculate),
- m_supports_watchpoint_support_info(eLazyBoolCalculate),
- m_supports_detach_stay_stopped(eLazyBoolCalculate),
- m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
- m_attach_or_wait_reply(eLazyBoolCalculate),
- m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
- m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
- m_avoid_g_packets(eLazyBoolCalculate),
- m_supports_QSaveRegisterState(eLazyBoolCalculate),
- m_supports_qXfer_auxv_read(eLazyBoolCalculate),
- m_supports_qXfer_libraries_read(eLazyBoolCalculate),
- m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
- m_supports_qXfer_features_read(eLazyBoolCalculate),
- m_supports_qXfer_memory_map_read(eLazyBoolCalculate),
- m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
- m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
- m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
- m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
- m_supports_QPassSignals(eLazyBoolCalculate),
- m_supports_error_string_reply(eLazyBoolCalculate),
+
m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
m_supports_qUserName(true), m_supports_qGroupName(true),
m_supports_qThreadStopInfo(true), m_supports_z0(true),
@@ -97,15 +65,11 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
- m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
- m_curr_tid_run(LLDB_INVALID_THREAD_ID),
- m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
- m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
- m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
- m_max_packet_size(0), m_qSupported_response(),
- m_supported_async_json_packets_is_valid(false),
- m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
- m_qXfer_memory_map_loaded(false) {}
+
+ m_host_arch(), m_process_arch(), m_os_build(), m_os_kernel(),
+ m_hostname(), m_gdb_server_name(), m_default_packet_timeout(0),
+ m_qSupported_response(), m_supported_async_json_packets_sp(),
+ m_qXfer_memory_map() {}
// Destructor
GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
@@ -218,7 +182,7 @@ bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
+ if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==
PacketResult::Success) {
if (response.IsOKResponse()) {
m_send_acks = false;
@@ -235,8 +199,8 @@ void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
m_supports_threads_in_stop_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
- false) == PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) ==
+ PacketResult::Success) {
if (response.IsOKResponse())
m_supports_threads_in_stop_reply = eLazyBoolYes;
}
@@ -248,8 +212,8 @@ bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
m_attach_or_wait_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
- false) == PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) ==
+ PacketResult::Success) {
if (response.IsOKResponse())
m_attach_or_wait_reply = eLazyBoolYes;
}
@@ -262,8 +226,8 @@ bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
m_prepare_for_reg_writing_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
- false) == PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) ==
+ PacketResult::Success) {
if (response.IsOKResponse())
m_prepare_for_reg_writing_reply = eLazyBoolYes;
}
@@ -292,6 +256,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
m_attach_or_wait_reply = eLazyBoolCalculate;
m_avoid_g_packets = eLazyBoolCalculate;
+ m_supports_multiprocess = eLazyBoolCalculate;
m_supports_qXfer_auxv_read = eLazyBoolCalculate;
m_supports_qXfer_libraries_read = eLazyBoolCalculate;
m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
@@ -321,6 +286,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_gdb_server_name.clear();
m_gdb_server_version = UINT32_MAX;
m_default_packet_timeout = seconds(0);
+ m_target_vm_page_size = 0;
m_max_packet_size = 0;
m_qSupported_response.clear();
m_supported_async_json_packets_is_valid = false;
@@ -342,11 +308,17 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
m_supports_qXfer_features_read = eLazyBoolNo;
m_supports_qXfer_memory_map_read = eLazyBoolNo;
+ m_supports_multiprocess = eLazyBoolNo;
+ m_supports_qEcho = eLazyBoolNo;
+ m_supports_QPassSignals = eLazyBoolNo;
+ m_supports_memory_tagging = eLazyBoolNo;
+
m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
// not, we assume no limit
// build the qSupported packet
- std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
+ std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",
+ "multiprocess+"};
StreamString packet;
packet.PutCString("qSupported");
for (uint32_t i = 0; i < features.size(); ++i) {
@@ -355,97 +327,57 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
}
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response,
- /*send_async=*/false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
- const char *response_cstr = response.GetStringRef().data();
-
// Hang on to the qSupported packet, so that platforms can do custom
// configuration of the transport before attaching/launching the process.
- m_qSupported_response = response_cstr;
-
- if (::strstr(response_cstr, "qXfer:auxv:read+"))
- m_supports_qXfer_auxv_read = eLazyBoolYes;
- if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
- m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
- if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
- m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
- m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
- }
- if (::strstr(response_cstr, "qXfer:libraries:read+"))
- m_supports_qXfer_libraries_read = eLazyBoolYes;
- if (::strstr(response_cstr, "qXfer:features:read+"))
- m_supports_qXfer_features_read = eLazyBoolYes;
- if (::strstr(response_cstr, "qXfer:memory-map:read+"))
- m_supports_qXfer_memory_map_read = eLazyBoolYes;
-
- // Look for a list of compressions in the features list e.g.
- // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
- // deflate,lzma
- const char *features_list = ::strstr(response_cstr, "qXfer:features:");
- if (features_list) {
- const char *compressions =
- ::strstr(features_list, "SupportedCompressions=");
- if (compressions) {
- std::vector<std::string> supported_compressions;
- compressions += sizeof("SupportedCompressions=") - 1;
- const char *end_of_compressions = strchr(compressions, ';');
- if (end_of_compressions == nullptr) {
- end_of_compressions = strchr(compressions, '\0');
- }
- const char *current_compression = compressions;
- while (current_compression < end_of_compressions) {
- const char *next_compression_name = strchr(current_compression, ',');
- const char *end_of_this_word = next_compression_name;
- if (next_compression_name == nullptr ||
- end_of_compressions < next_compression_name) {
- end_of_this_word = end_of_compressions;
- }
-
- if (end_of_this_word) {
- if (end_of_this_word == current_compression) {
- current_compression++;
- } else {
- std::string this_compression(
- current_compression, end_of_this_word - current_compression);
- supported_compressions.push_back(this_compression);
- current_compression = end_of_this_word + 1;
- }
- } else {
- supported_compressions.push_back(current_compression);
- current_compression = end_of_compressions;
- }
- }
-
- if (supported_compressions.size() > 0) {
- MaybeEnableCompression(supported_compressions);
+ m_qSupported_response = response.GetStringRef().str();
+
+ llvm::SmallVector<llvm::StringRef, 16> server_features;
+ response.GetStringRef().split(server_features, ';');
+
+ for (llvm::StringRef x : server_features) {
+ if (x == "qXfer:auxv:read+")
+ m_supports_qXfer_auxv_read = eLazyBoolYes;
+ else if (x == "qXfer:libraries-svr4:read+")
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
+ else if (x == "augmented-libraries-svr4-read") {
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
+ m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
+ } else if (x == "qXfer:libraries:read+")
+ m_supports_qXfer_libraries_read = eLazyBoolYes;
+ else if (x == "qXfer:features:read+")
+ m_supports_qXfer_features_read = eLazyBoolYes;
+ else if (x == "qXfer:memory-map:read+")
+ m_supports_qXfer_memory_map_read = eLazyBoolYes;
+ else if (x == "qEcho")
+ m_supports_qEcho = eLazyBoolYes;
+ else if (x == "QPassSignals+")
+ m_supports_QPassSignals = eLazyBoolYes;
+ else if (x == "multiprocess+")
+ m_supports_multiprocess = eLazyBoolYes;
+ else if (x == "memory-tagging+")
+ m_supports_memory_tagging = eLazyBoolYes;
+ // Look for a list of compressions in the features list e.g.
+ // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
+ // deflate,lzma
+ else if (x.consume_front("SupportedCompressions=")) {
+ llvm::SmallVector<llvm::StringRef, 4> compressions;
+ x.split(compressions, ',');
+ if (!compressions.empty())
+ MaybeEnableCompression(compressions);
+ } else if (x.consume_front("PacketSize=")) {
+ StringExtractorGDBRemote packet_response(x);
+ m_max_packet_size =
+ packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
+ if (m_max_packet_size == 0) {
+ m_max_packet_size = UINT64_MAX; // Must have been a garbled response
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
}
}
}
-
- if (::strstr(response_cstr, "qEcho"))
- m_supports_qEcho = eLazyBoolYes;
- else
- m_supports_qEcho = eLazyBoolNo;
-
- if (::strstr(response_cstr, "QPassSignals+"))
- m_supports_QPassSignals = eLazyBoolYes;
- else
- m_supports_QPassSignals = eLazyBoolNo;
-
- const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
- if (packet_size_str) {
- StringExtractorGDBRemote packet_response(packet_size_str +
- strlen("PacketSize="));
- m_max_packet_size =
- packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
- if (m_max_packet_size == 0) {
- m_max_packet_size = UINT64_MAX; // Must have been a garbled response
- Log *log(
- ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
- }
- }
}
}
@@ -453,8 +385,8 @@ bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
if (m_supports_thread_suffix == eLazyBoolCalculate) {
StringExtractorGDBRemote response;
m_supports_thread_suffix = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
- false) == PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) ==
+ PacketResult::Success) {
if (response.IsOKResponse())
m_supports_thread_suffix = eLazyBoolYes;
}
@@ -470,7 +402,7 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
m_supports_vCont_C = eLazyBoolNo;
m_supports_vCont_s = eLazyBoolNo;
m_supports_vCont_S = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("vCont?", response, false) ==
+ if (SendPacketAndWaitForResponse("vCont?", response) ==
PacketResult::Success) {
const char *response_cstr = response.GetStringRef().data();
if (::strstr(response_cstr, ";c"))
@@ -522,9 +454,9 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
- lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
- bool send_async) {
- Lock lock(*this, send_async);
+ lldb::tid_t tid, StreamString &&payload,
+ StringExtractorGDBRemote &response) {
+ Lock lock(*this);
if (!lock) {
if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
@@ -561,7 +493,7 @@ LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(
payload.PutCString(packetStr);
StringExtractorGDBRemote response;
if (SendThreadSpecificPacketAndWaitForResponse(
- tid, std::move(payload), response, false) == PacketResult::Success &&
+ tid, std::move(payload), response) == PacketResult::Success &&
response.IsNormalResponse()) {
return eLazyBoolYes;
}
@@ -575,7 +507,7 @@ StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
if (m_supports_jThreadsInfo) {
StringExtractorGDBRemote response;
response.SetResponseValidatorToJSON();
- if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
+ if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==
PacketResult::Success) {
if (response.IsUnsupportedResponse()) {
m_supports_jThreadsInfo = false;
@@ -592,7 +524,7 @@ bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
StringExtractorGDBRemote response;
m_supports_jThreadExtendedInfo = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
+ if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) ==
PacketResult::Success) {
if (response.IsOKResponse()) {
m_supports_jThreadExtendedInfo = eLazyBoolYes;
@@ -608,7 +540,7 @@ void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
// We try to enable error strings in remote packets but if we fail, we just
// work in the older way.
m_supports_error_string_reply = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
+ if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==
PacketResult::Success) {
if (response.IsOKResponse()) {
m_supports_error_string_reply = eLazyBoolYes;
@@ -622,8 +554,7 @@ bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
StringExtractorGDBRemote response;
m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
- response,
- false) == PacketResult::Success) {
+ response) == PacketResult::Success) {
if (response.IsOKResponse()) {
m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
}
@@ -636,7 +567,7 @@ bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
StringExtractorGDBRemote response;
m_supports_jGetSharedCacheInfo = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
+ if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) ==
PacketResult::Success) {
if (response.IsOKResponse()) {
m_supports_jGetSharedCacheInfo = eLazyBoolYes;
@@ -646,13 +577,82 @@ bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
return m_supports_jGetSharedCacheInfo;
}
+bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
+ if (m_supports_memory_tagging == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_memory_tagging == eLazyBoolYes;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,
+ size_t len,
+ int32_t type) {
+ StreamString packet;
+ packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);
+ StringExtractorGDBRemote response;
+
+ Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_MEMORY);
+
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
+ PacketResult::Success ||
+ !response.IsNormalResponse()) {
+ LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ // We are expecting
+ // m<hex encoded bytes>
+
+ if (response.GetChar() != 'm') {
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s: qMemTags response did not "
+ "begin with \"m\"",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ size_t expected_bytes = response.GetBytesLeft() / 2;
+ DataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
+ size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
+ // Check both because in some situations chars are consumed even
+ // if the decoding fails.
+ if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ return buffer_sp;
+}
+
+Status GDBRemoteCommunicationClient::WriteMemoryTags(
+ lldb::addr_t addr, size_t len, int32_t type,
+ const std::vector<uint8_t> &tags) {
+ // Format QMemTags:address,length:type:tags
+ StreamString packet;
+ packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);
+ packet.PutBytesAsRawHex8(tags.data(), tags.size());
+
+ Status status;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
+ PacketResult::Success ||
+ !response.IsOKResponse()) {
+ status.SetErrorString("QMemTags packet failed");
+ }
+ return status;
+}
+
bool GDBRemoteCommunicationClient::GetxPacketSupported() {
if (m_supports_x == eLazyBoolCalculate) {
StringExtractorGDBRemote response;
m_supports_x = eLazyBoolNo;
char packet[256];
snprintf(packet, sizeof(packet), "x0,0");
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
if (response.IsOKResponse())
m_supports_x = eLazyBoolYes;
@@ -664,7 +664,7 @@ bool GDBRemoteCommunicationClient::GetxPacketSupported() {
GDBRemoteCommunicationClient::PacketResult
GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
const char *payload_prefix, std::string &response_string) {
- Lock lock(*this, false);
+ Lock lock(*this);
if (!lock) {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
GDBR_LOG_PACKETS));
@@ -725,11 +725,11 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
// the thread id, which newer debugserver and lldb-gdbserver stubs return
// correctly.
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC", response, false) ==
- PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("qC", response) == PacketResult::Success) {
if (response.GetChar() == 'Q') {
if (response.GetChar() == 'C') {
- m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
+ m_curr_pid_run = m_curr_pid =
+ response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
m_curr_pid_is_valid = eLazyBoolYes;
return m_curr_pid;
@@ -741,12 +741,14 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
// If we don't get a response for $qC, check if $qfThreadID gives us a
// result.
if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
- std::vector<lldb::tid_t> thread_ids;
bool sequence_mutex_unavailable;
- size_t size;
- size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
- if (size && !sequence_mutex_unavailable) {
- m_curr_pid = thread_ids.front();
+ auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
+ if (!ids.empty() && !sequence_mutex_unavailable) {
+ // If server returned an explicit PID, use that.
+ m_curr_pid_run = m_curr_pid = ids.front().first;
+ // Otherwise, use the TID of the first thread (Linux hack).
+ if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
+ m_curr_pid_run = m_curr_pid = ids.front().second;
m_curr_pid_is_valid = eLazyBoolYes;
return m_curr_pid;
}
@@ -759,7 +761,7 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
error_str.clear();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
+ if (SendPacketAndWaitForResponse("qLaunchSuccess", response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return true;
@@ -813,7 +815,7 @@ int GDBRemoteCommunicationClient::SendArgumentsPacket(
}
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -863,7 +865,7 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket(
if (m_supports_QEnvironmentHexEncoded) {
packet.PutCString("QEnvironmentHexEncoded:");
packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -877,7 +879,7 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket(
} else if (m_supports_QEnvironment) {
packet.Printf("QEnvironment:%s", name_equal_value);
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -897,7 +899,7 @@ int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
StreamString packet;
packet.Printf("QLaunchArch:%s", arch);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -915,7 +917,7 @@ int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
StreamString packet;
packet.Printf("QSetProcessEvent:%s", data);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse()) {
if (was_supported)
@@ -1000,7 +1002,7 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
m_qGDBServerVersion_is_valid = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
+ if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==
PacketResult::Success) {
if (response.IsNormalResponse()) {
llvm::StringRef name, value;
@@ -1025,9 +1027,9 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
}
void GDBRemoteCommunicationClient::MaybeEnableCompression(
- std::vector<std::string> supported_compressions) {
+ llvm::ArrayRef<llvm::StringRef> supported_compressions) {
CompressionType avail_type = CompressionType::None;
- std::string avail_name;
+ llvm::StringRef avail_name;
#if defined(HAVE_LIBCOMPRESSION)
if (avail_type == CompressionType::None) {
@@ -1091,8 +1093,8 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
if (avail_type != CompressionType::None) {
StringExtractorGDBRemote response;
- std::string packet = "QEnableCompression:type:" + avail_name + ";";
- if (SendPacketAndWaitForResponse(packet, response, false) !=
+ llvm::Twine packet = "QEnableCompression:type:" + avail_name + ";";
+ if (SendPacketAndWaitForResponse(packet.str(), response) !=
PacketResult::Success)
return;
@@ -1118,15 +1120,29 @@ uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC", response, false) !=
- PacketResult::Success)
+ if (SendPacketAndWaitForResponse("qC", response) != PacketResult::Success)
return false;
if (!response.IsNormalResponse())
return false;
- if (response.GetChar() == 'Q' && response.GetChar() == 'C')
- tid = response.GetHexMaxU32(true, -1);
+ if (response.GetChar() == 'Q' && response.GetChar() == 'C') {
+ auto pid_tid = response.GetPidTid(0);
+ if (!pid_tid)
+ return false;
+
+ lldb::pid_t pid = pid_tid->first;
+ // invalid
+ if (pid == StringExtractorGDBRemote::AllProcesses)
+ return false;
+
+ // if we get pid as well, update m_curr_pid
+ if (pid != 0) {
+ m_curr_pid_run = m_curr_pid = pid;
+ m_curr_pid_is_valid = eLazyBoolYes;
+ }
+ tid = pid_tid->second;
+ }
return true;
}
@@ -1154,7 +1170,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
ScopedTimeout timeout(*this, seconds(10));
m_qHostInfo_is_valid = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
+ if (SendPacketAndWaitForResponse("qHostInfo", response) ==
PacketResult::Success) {
if (response.IsNormalResponse()) {
llvm::StringRef name;
@@ -1219,11 +1235,13 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
} else if (name.equals("ptrsize")) {
if (!value.getAsInteger(0, pointer_byte_size))
++num_keys_decoded;
+ } else if (name.equals("addressing_bits")) {
+ if (!value.getAsInteger(0, m_addressing_bits))
+ ++num_keys_decoded;
} else if (name.equals("os_version") ||
- name.equals(
- "version")) // Older debugserver binaries used the
- // "version" key instead of
- // "os_version"...
+ name.equals("version")) // Older debugserver binaries used
+ // the "version" key instead of
+ // "os_version"...
{
if (!m_os_version.tryParse(value))
++num_keys_decoded;
@@ -1245,6 +1263,12 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
SetPacketTimeout(m_default_packet_timeout);
++num_keys_decoded;
}
+ } else if (name.equals("vm-page-size")) {
+ int page_size;
+ if (!value.getAsInteger(0, page_size)) {
+ m_target_vm_page_size = page_size;
+ ++num_keys_decoded;
+ }
}
}
@@ -1344,7 +1368,7 @@ int GDBRemoteCommunicationClient::SendAttach(
::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
UNUSED_IF_ASSERT_DISABLED(packet_len);
assert(packet_len < (int)sizeof(packet));
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
if (response.IsErrorResponse())
return response.GetError();
@@ -1360,7 +1384,7 @@ int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
packet.PutCString("I");
packet.PutBytesAsRawHex8(data, data_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
return 0;
}
@@ -1374,6 +1398,11 @@ GDBRemoteCommunicationClient::GetHostArchitecture() {
return m_host_arch;
}
+uint32_t GDBRemoteCommunicationClient::GetAddressingBits() {
+ if (m_qHostInfo_is_valid == eLazyBoolCalculate)
+ GetHostInfo();
+ return m_addressing_bits;
+}
seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
GetHostInfo();
@@ -1393,7 +1422,7 @@ addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
if (response.IsUnsupportedResponse())
m_supports_alloc_dealloc_memory = eLazyBoolNo;
@@ -1415,7 +1444,7 @@ bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
if (response.IsUnsupportedResponse())
m_supports_alloc_dealloc_memory = eLazyBoolNo;
@@ -1439,7 +1468,7 @@ Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success &&
response.IsOKResponse()) {
m_supports_detach_stay_stopped = eLazyBoolYes;
@@ -1453,15 +1482,13 @@ Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
return error;
} else {
StringExtractorGDBRemote response;
- PacketResult packet_result =
- SendPacketAndWaitForResponse("D1", response, false);
+ PacketResult packet_result = SendPacketAndWaitForResponse("D1", response);
if (packet_result != PacketResult::Success)
error.SetErrorString("Sending extended disconnect packet failed.");
}
} else {
StringExtractorGDBRemote response;
- PacketResult packet_result =
- SendPacketAndWaitForResponse("D", response, false);
+ PacketResult packet_result = SendPacketAndWaitForResponse("D", response);
if (packet_result != PacketResult::Success)
error.SetErrorString("Sending disconnect packet failed.");
}
@@ -1481,7 +1508,7 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success &&
response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
llvm::StringRef name;
@@ -1551,9 +1578,30 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
// Now convert the HEX bytes into a string value
error_extractor.GetHexByteString(error_string);
error.SetErrorString(error_string.c_str());
+ } else if (name.equals("dirty-pages")) {
+ std::vector<addr_t> dirty_page_list;
+ std::string comma_sep_str = value.str();
+ size_t comma_pos;
+ addr_t page;
+ while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) {
+ comma_sep_str[comma_pos] = '\0';
+ page = StringConvert::ToUInt64(comma_sep_str.c_str(),
+ LLDB_INVALID_ADDRESS, 16);
+ if (page != LLDB_INVALID_ADDRESS)
+ dirty_page_list.push_back(page);
+ comma_sep_str.erase(0, comma_pos + 1);
+ }
+ page = StringConvert::ToUInt64(comma_sep_str.c_str(),
+ LLDB_INVALID_ADDRESS, 16);
+ if (page != LLDB_INVALID_ADDRESS)
+ dirty_page_list.push_back(page);
+ region_info.SetDirtyPageList(dirty_page_list);
}
}
+ if (m_target_vm_page_size != 0)
+ region_info.SetPageSize(m_target_vm_page_size);
+
if (region_info.GetRange().IsValid()) {
// We got a valid address range back but no permissions -- which means
// this is an unmapped page
@@ -1718,8 +1766,8 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
num = 0;
if (m_supports_watchpoint_support_info != eLazyBoolNo) {
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response,
- false) == PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==
+ PacketResult::Success) {
m_supports_watchpoint_support_info = eLazyBoolYes;
llvm::StringRef name;
llvm::StringRef value;
@@ -1787,7 +1835,7 @@ int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -1807,7 +1855,7 @@ int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -1827,7 +1875,7 @@ int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -1841,7 +1889,7 @@ int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
+ if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==
PacketResult::Success) {
if (response.IsUnsupportedResponse())
return false;
@@ -1863,7 +1911,7 @@ int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return 0;
@@ -1882,8 +1930,7 @@ int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
- PacketResult::Success) {
+ if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
if (response.IsOKResponse())
return 0;
uint8_t error = response.GetError();
@@ -1900,8 +1947,7 @@ int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
- PacketResult::Success) {
+ if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
if (response.IsOKResponse())
return 0;
uint8_t error = response.GetError();
@@ -2019,7 +2065,7 @@ bool GDBRemoteCommunicationClient::GetProcessInfo(
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
return DecodeProcessInfoResponse(response, process_info);
} else {
@@ -2044,7 +2090,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
GetHostInfo();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
+ if (SendPacketAndWaitForResponse("qProcessInfo", response) ==
PacketResult::Success) {
if (response.IsNormalResponse()) {
llvm::StringRef name;
@@ -2102,7 +2148,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
m_qProcessInfo_is_valid = eLazyBoolYes;
if (pid != LLDB_INVALID_PROCESS_ID) {
m_curr_pid_is_valid = eLazyBoolYes;
- m_curr_pid = pid;
+ m_curr_pid_run = m_curr_pid = pid;
}
// Set the ArchSpec from the triple if we have it.
@@ -2240,7 +2286,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
// Increase timeout as the first qfProcessInfo packet takes a long time on
// Android. The value of 1min was arrived at empirically.
ScopedTimeout timeout(*this, minutes(1));
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success) {
do {
ProcessInstanceInfo process_info;
@@ -2248,7 +2294,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
break;
process_infos.push_back(process_info);
response = StringExtractorGDBRemote();
- } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
+ } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==
PacketResult::Success);
} else {
m_supports_qfProcessInfo = false;
@@ -2267,7 +2313,7 @@ bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
if (response.IsNormalResponse()) {
// Make sure we parsed the right number of characters. The response is
@@ -2294,7 +2340,7 @@ bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
if (response.IsNormalResponse()) {
// Make sure we parsed the right number of characters. The response is
@@ -2322,8 +2368,7 @@ bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
StringExtractorGDBRemote response;
// Send to target
- if (SendPacketAndWaitForResponse(packet, response, false) ==
- PacketResult::Success)
+ if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success)
if (response.IsOKResponse())
return true;
@@ -2395,7 +2440,7 @@ void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
for (i = 0; i < num_packets; ++i) {
const auto packet_start_time = steady_clock::now();
StringExtractorGDBRemote response;
- SendPacketAndWaitForResponse(packet.GetString(), response, false);
+ SendPacketAndWaitForResponse(packet.GetString(), response);
const auto packet_end_time = steady_clock::now();
packet_times.push_back(packet_end_time - packet_start_time);
}
@@ -2449,7 +2494,7 @@ void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
uint32_t packet_count = 0;
while (bytes_read < recv_amount) {
StringExtractorGDBRemote response;
- SendPacketAndWaitForResponse(packet.GetString(), response, false);
+ SendPacketAndWaitForResponse(packet.GetString(), response);
bytes_read += recv_size;
++packet_count;
}
@@ -2503,7 +2548,7 @@ bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
}
StringExtractorGDBRemote response;
- return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ return SendPacketAndWaitForResponse(packet.GetString(), response) ==
PacketResult::Success;
}
@@ -2533,7 +2578,7 @@ bool GDBRemoteCommunicationClient::LaunchGDBServer(
// give the process a few seconds to startup
ScopedTimeout timeout(*this, seconds(10));
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
llvm::StringRef name;
llvm::StringRef value;
@@ -2557,7 +2602,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer(
connection_urls.clear();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
+ if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=
PacketResult::Success)
return 0;
@@ -2596,7 +2641,7 @@ bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.IsOKResponse())
return true;
@@ -2604,25 +2649,27 @@ bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
return false;
}
-bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
- if (m_curr_tid == tid)
- return true;
+llvm::Optional<PidTid>
+GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid,
+ uint64_t pid,
+ char op) {
+ lldb_private::StreamString packet;
+ packet.PutChar('H');
+ packet.PutChar(op);
+
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ packet.Printf("p%" PRIx64 ".", pid);
- char packet[32];
- int packet_len;
if (tid == UINT64_MAX)
- packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
+ packet.PutCString("-1");
else
- packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
- assert(packet_len + 1 < (int)sizeof(packet));
- UNUSED_IF_ASSERT_DISABLED(packet_len);
+ packet.Printf("%" PRIx64, tid);
+
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
- PacketResult::Success) {
- if (response.IsOKResponse()) {
- m_curr_tid = tid;
- return true;
- }
+ if (SendPacketAndWaitForResponse(packet.GetString(), response)
+ == PacketResult::Success) {
+ if (response.IsOKResponse())
+ return {{pid, tid}};
/*
* Connected bare-iron target (like YAMON gdb-stub) may not have support for
@@ -2630,55 +2677,46 @@ bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
* The reply from '?' packet could be as simple as 'S05'. There is no packet
* which can
* give us pid and/or tid. Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && IsConnected()) {
- m_curr_tid = 1;
- return true;
- }
+ */
+ if (response.IsUnsupportedResponse() && IsConnected())
+ return {{1, 1}};
}
- return false;
+ return llvm::None;
}
-bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
- if (m_curr_tid_run == tid)
+bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,
+ uint64_t pid) {
+ if (m_curr_tid == tid &&
+ (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))
return true;
- char packet[32];
- int packet_len;
- if (tid == UINT64_MAX)
- packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
- else
- packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
+ llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
+ if (ret.hasValue()) {
+ if (ret->pid != LLDB_INVALID_PROCESS_ID)
+ m_curr_pid = ret->pid;
+ m_curr_tid = ret->tid;
+ }
+ return ret.hasValue();
+}
- assert(packet_len + 1 < (int)sizeof(packet));
- UNUSED_IF_ASSERT_DISABLED(packet_len);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
- PacketResult::Success) {
- if (response.IsOKResponse()) {
- m_curr_tid_run = tid;
- return true;
- }
+bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,
+ uint64_t pid) {
+ if (m_curr_tid_run == tid &&
+ (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))
+ return true;
- /*
- * Connected bare-iron target (like YAMON gdb-stub) may not have support for
- * Hc packet.
- * The reply from '?' packet could be as simple as 'S05'. There is no packet
- * which can
- * give us pid and/or tid. Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && IsConnected()) {
- m_curr_tid_run = 1;
- return true;
- }
+ llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
+ if (ret.hasValue()) {
+ if (ret->pid != LLDB_INVALID_PROCESS_ID)
+ m_curr_pid_run = ret->pid;
+ m_curr_tid_run = ret->tid;
}
- return false;
+ return ret.hasValue();
}
bool GDBRemoteCommunicationClient::GetStopReply(
StringExtractorGDBRemote &response) {
- if (SendPacketAndWaitForResponse("?", response, false) ==
- PacketResult::Success)
+ if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success)
return response.IsNormalResponse();
return false;
}
@@ -2691,7 +2729,7 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo(
::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
- if (SendPacketAndWaitForResponse(packet, response, false) ==
+ if (SendPacketAndWaitForResponse(packet, response) ==
PacketResult::Success) {
if (response.IsUnsupportedResponse())
m_supports_qThreadStopInfo = false;
@@ -2707,7 +2745,8 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo(
}
uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
- GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
+ GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
+ std::chrono::seconds timeout) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
__FUNCTION__, insert ? "add" : "remove", addr);
@@ -2728,7 +2767,7 @@ uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
// or "" (unsupported)
response.SetResponseValidatorToOKErrorNotSupported();
// Try to send the breakpoint packet, and check that it was correctly sent
- if (SendPacketAndWaitForResponse(packet, response, true) ==
+ if (SendPacketAndWaitForResponse(packet, response, timeout) ==
PacketResult::Success) {
// Receive and OK packet when the breakpoint successfully placed
if (response.IsOKResponse())
@@ -2766,11 +2805,12 @@ uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
return UINT8_MAX;
}
-size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
- std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
- thread_ids.clear();
+std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
+GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(
+ bool &sequence_mutex_unavailable) {
+ std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
- Lock lock(*this, false);
+ Lock lock(*this);
if (lock) {
sequence_mutex_unavailable = false;
StringExtractorGDBRemote response;
@@ -2786,11 +2826,11 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
break;
if (ch == 'm') {
do {
- tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
+ auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);
+ if (!pid_tid)
+ return {};
- if (tid != LLDB_INVALID_THREAD_ID) {
- thread_ids.push_back(tid);
- }
+ ids.push_back(pid_tid.getValue());
ch = response.GetChar(); // Skip the command separator
} while (ch == ','); // Make sure we got a comma separator
}
@@ -2803,10 +2843,10 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
* be as simple as 'S05'. There is no packet which can give us pid and/or
* tid.
* Assume pid=tid=1 in such cases.
- */
+ */
if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
- thread_ids.size() == 0 && IsConnected()) {
- thread_ids.push_back(1);
+ ids.size() == 0 && IsConnected()) {
+ ids.emplace_back(1, 1);
}
} else {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
@@ -2815,12 +2855,34 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
"packet 'qfThreadInfo'");
sequence_mutex_unavailable = true;
}
+
+ return ids;
+}
+
+size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
+ std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
+ lldb::pid_t pid = GetCurrentProcessID();
+ thread_ids.clear();
+
+ auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
+ if (ids.empty() || sequence_mutex_unavailable)
+ return 0;
+
+ for (auto id : ids) {
+ // skip threads that do not belong to the current process
+ if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)
+ continue;
+ if (id.second != LLDB_INVALID_THREAD_ID &&
+ id.second != StringExtractorGDBRemote::AllThreads)
+ thread_ids.push_back(id.second);
+ }
+
return thread_ids.size();
}
lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
+ if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=
PacketResult::Success ||
!response.IsNormalResponse())
return LLDB_INVALID_ADDRESS;
@@ -2853,7 +2915,7 @@ lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
stream.PutStringAsRawHex8(path);
}
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() != 'F')
return Status("malformed reply");
@@ -2891,8 +2953,7 @@ Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
llvm::StringRef packet = stream.GetString();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) !=
- PacketResult::Success)
+ if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
return Status("failed to send '%s' packet", packet.str().c_str());
if (response.GetChar() != 'F')
@@ -2913,8 +2974,7 @@ GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
llvm::StringRef packet = stream.GetString();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) !=
- PacketResult::Success)
+ if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
return Status("failed to send '%s' packet", stream.GetData());
if (response.GetChar() != 'F')
@@ -2956,7 +3016,7 @@ GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
stream.PutChar(',');
stream.PutHex32(mode);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
return ParseHostIOPacketResponse(response, UINT64_MAX, error);
}
@@ -2968,7 +3028,7 @@ bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
lldb_private::StreamString stream;
stream.Printf("vFile:close:%i", (int)fd);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
return ParseHostIOPacketResponse(response, -1, error) == 0;
}
@@ -2983,7 +3043,7 @@ lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
stream.PutCString("vFile:size:");
stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() != 'F')
return UINT64_MAX;
@@ -3001,7 +3061,7 @@ void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(
stream.PutChar(',');
stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix());
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
StreamString strm;
char ch = response.GetChar();
@@ -3027,7 +3087,7 @@ GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
stream.PutCString("vFile:mode:");
stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() != 'F') {
error.SetErrorStringWithFormat("invalid response to '%s' packet",
@@ -3062,7 +3122,7 @@ uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
offset);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() != 'F')
return 0;
@@ -3096,7 +3156,7 @@ uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
stream.PutEscapedBytes(src, src_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() != 'F') {
error.SetErrorStringWithFormat("write file failed");
@@ -3131,7 +3191,7 @@ Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
stream.PutChar(',');
stream.PutStringAsRawHex8(src_path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() == 'F') {
uint32_t result = response.GetU32(UINT32_MAX);
@@ -3162,7 +3222,7 @@ Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
// so we follow suit here
stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() == 'F') {
uint32_t result = response.GetU32(UINT32_MAX);
@@ -3192,7 +3252,7 @@ bool GDBRemoteCommunicationClient::GetFileExists(
stream.PutCString("vFile:exists:");
stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() != 'F')
return false;
@@ -3211,7 +3271,7 @@ bool GDBRemoteCommunicationClient::CalculateMD5(
stream.PutCString("vFile:MD5:");
stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
PacketResult::Success) {
if (response.GetChar() != 'F')
return false;
@@ -3258,7 +3318,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
payload.Printf("p%x", reg);
StringExtractorGDBRemote response;
if (SendThreadSpecificPacketAndWaitForResponse(
- tid, std::move(payload), response, false) != PacketResult::Success ||
+ tid, std::move(payload), response) != PacketResult::Success ||
!response.IsNormalResponse())
return nullptr;
@@ -3273,7 +3333,7 @@ DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
payload.PutChar('g');
StringExtractorGDBRemote response;
if (SendThreadSpecificPacketAndWaitForResponse(
- tid, std::move(payload), response, false) != PacketResult::Success ||
+ tid, std::move(payload), response) != PacketResult::Success ||
!response.IsNormalResponse())
return nullptr;
@@ -3292,9 +3352,8 @@ bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
endian::InlHostByteOrder(),
endian::InlHostByteOrder());
StringExtractorGDBRemote response;
- return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
- response, false) ==
- PacketResult::Success &&
+ return SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response) == PacketResult::Success &&
response.IsOKResponse();
}
@@ -3306,9 +3365,8 @@ bool GDBRemoteCommunicationClient::WriteAllRegisters(
endian::InlHostByteOrder(),
endian::InlHostByteOrder());
StringExtractorGDBRemote response;
- return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
- response, false) ==
- PacketResult::Success &&
+ return SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response) == PacketResult::Success &&
response.IsOKResponse();
}
@@ -3323,7 +3381,7 @@ bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
payload.PutCString("QSaveRegisterState");
StringExtractorGDBRemote response;
if (SendThreadSpecificPacketAndWaitForResponse(
- tid, std::move(payload), response, false) != PacketResult::Success)
+ tid, std::move(payload), response) != PacketResult::Success)
return false;
if (response.IsUnsupportedResponse())
@@ -3349,7 +3407,7 @@ bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
payload.Printf("QRestoreRegisterState:%u", save_id);
StringExtractorGDBRemote response;
if (SendThreadSpecificPacketAndWaitForResponse(
- tid, std::move(payload), response, false) != PacketResult::Success)
+ tid, std::move(payload), response) != PacketResult::Success)
return false;
if (response.IsOKResponse())
@@ -3367,251 +3425,179 @@ bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
StreamString packet;
StringExtractorGDBRemote response;
packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
- return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ return SendPacketAndWaitForResponse(packet.GetString(), response) ==
GDBRemoteCommunication::PacketResult::Success &&
response.IsOKResponse();
}
-lldb::user_id_t
-GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
- Status &error) {
+llvm::Expected<TraceSupportedResponse>
+GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- lldb::user_id_t ret_uid = LLDB_INVALID_UID;
StreamGDBRemote escaped_packet;
- escaped_packet.PutCString("jTraceStart:");
-
- StructuredData::Dictionary json_packet;
- json_packet.AddIntegerItem("type", options.getType());
- json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
- json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
-
- if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
- json_packet.AddIntegerItem("threadid", options.getThreadID());
-
- StructuredData::DictionarySP custom_params = options.getTraceParams();
- if (custom_params)
- json_packet.AddItem("params", custom_params);
-
- StreamString json_string;
- json_packet.Dump(json_string, false);
- escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
+ escaped_packet.PutCString("jLLDBTraceSupported");
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
- true) ==
+ timeout) ==
GDBRemoteCommunication::PacketResult::Success) {
- if (!response.IsNormalResponse()) {
- error = response.GetStatus();
- LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
- } else {
- ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
- }
- } else {
- LLDB_LOG(log, "failed to send packet");
- error.SetErrorStringWithFormat("failed to send packet: '%s'",
- escaped_packet.GetData());
+ if (response.IsErrorResponse())
+ return response.GetStatus().ToError();
+ if (response.IsUnsupportedResponse())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "jLLDBTraceSupported is unsupported");
+
+ return llvm::json::parse<TraceSupportedResponse>(response.Peek(),
+ "TraceSupportedResponse");
}
- return ret_uid;
+ LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "failed to send packet: jLLDBTraceSupported");
}
-Status
-GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
- lldb::tid_t thread_id) {
+llvm::Error
+GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request,
+ std::chrono::seconds timeout) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- StringExtractorGDBRemote response;
- Status error;
- StructuredData::Dictionary json_packet;
StreamGDBRemote escaped_packet;
- StreamString json_string;
- escaped_packet.PutCString("jTraceStop:");
-
- json_packet.AddIntegerItem("traceid", uid);
+ escaped_packet.PutCString("jLLDBTraceStop:");
- if (thread_id != LLDB_INVALID_THREAD_ID)
- json_packet.AddIntegerItem("threadid", thread_id);
+ std::string json_string;
+ llvm::raw_string_ostream os(json_string);
+ os << toJSON(request);
+ os.flush();
- json_packet.Dump(json_string, false);
-
- escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
+ escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
+ StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
- true) ==
+ timeout) ==
GDBRemoteCommunication::PacketResult::Success) {
- if (!response.IsOKResponse()) {
- error = response.GetStatus();
- LLDB_LOG(log, "stop tracing failed");
- }
- } else {
- LLDB_LOG(log, "failed to send packet");
- error.SetErrorStringWithFormat(
- "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
- response.GetError());
+ if (response.IsErrorResponse())
+ return response.GetStatus().ToError();
+ if (response.IsUnsupportedResponse())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "jLLDBTraceStop is unsupported");
+ if (response.IsOKResponse())
+ return llvm::Error::success();
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid jLLDBTraceStart response");
}
- return error;
+ LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "failed to send packet: jLLDBTraceStop '%s'",
+ escaped_packet.GetData());
}
-Status GDBRemoteCommunicationClient::SendGetDataPacket(
- lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+llvm::Error
+GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
+ std::chrono::seconds timeout) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
StreamGDBRemote escaped_packet;
- escaped_packet.PutCString("jTraceBufferRead:");
- return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
-}
-
-Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
- lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+ escaped_packet.PutCString("jLLDBTraceStart:");
- StreamGDBRemote escaped_packet;
- escaped_packet.PutCString("jTraceMetaRead:");
- return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
-}
+ std::string json_string;
+ llvm::raw_string_ostream os(json_string);
+ os << params;
+ os.flush();
-llvm::Expected<TraceTypeInfo>
-GDBRemoteCommunicationClient::SendGetSupportedTraceType() {
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-
- StreamGDBRemote escaped_packet;
- escaped_packet.PutCString("jLLDBTraceSupportedType");
+ escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
- true) ==
+ timeout) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsErrorResponse())
return response.GetStatus().ToError();
if (response.IsUnsupportedResponse())
return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "jLLDBTraceSupportedType is unsupported");
-
- if (llvm::Expected<TraceTypeInfo> type =
- llvm::json::parse<TraceTypeInfo>(response.Peek()))
- return *type;
- else
- return type.takeError();
+ "jLLDBTraceStart is unsupported");
+ if (response.IsOKResponse())
+ return llvm::Error::success();
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid jLLDBTraceStart response");
}
- LLDB_LOG(log, "failed to send packet: jLLDBTraceSupportedType");
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(),
- "failed to send packet: jLLDBTraceSupportedType");
+ LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "failed to send packet: jLLDBTraceStart '%s'",
+ escaped_packet.GetData());
}
-Status
-GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
- TraceOptions &options) {
+llvm::Expected<std::string>
+GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type,
+ std::chrono::seconds timeout) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- StringExtractorGDBRemote response;
- Status error;
- StreamString json_string;
StreamGDBRemote escaped_packet;
- escaped_packet.PutCString("jTraceConfigRead:");
-
- StructuredData::Dictionary json_packet;
- json_packet.AddIntegerItem("traceid", uid);
+ escaped_packet.PutCString("jLLDBTraceGetState:");
- if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
- json_packet.AddIntegerItem("threadid", options.getThreadID());
+ std::string json_string;
+ llvm::raw_string_ostream os(json_string);
+ os << toJSON(TraceGetStateRequest{type.str()});
+ os.flush();
- json_packet.Dump(json_string, false);
- escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
+ escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
+ StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
- true) ==
+ timeout) ==
GDBRemoteCommunication::PacketResult::Success) {
- if (response.IsNormalResponse()) {
- uint64_t type = std::numeric_limits<uint64_t>::max();
- uint64_t buffersize = std::numeric_limits<uint64_t>::max();
- uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
-
- auto json_object = StructuredData::ParseJSON(response.Peek());
-
- if (!json_object ||
- json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
- error.SetErrorString("Invalid Configuration obtained");
- return error;
- }
-
- auto json_dict = json_object->GetAsDictionary();
-
- json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
- metabuffersize);
- options.setMetaDataBufferSize(metabuffersize);
-
- json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
- options.setTraceBufferSize(buffersize);
-
- json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
- options.setType(static_cast<lldb::TraceType>(type));
-
- StructuredData::ObjectSP custom_params_sp =
- json_dict->GetValueForKey("params");
- if (custom_params_sp) {
- if (custom_params_sp->GetType() !=
- lldb::eStructuredDataTypeDictionary) {
- error.SetErrorString("Invalid Configuration obtained");
- return error;
- } else
- options.setTraceParams(
- std::static_pointer_cast<StructuredData::Dictionary>(
- custom_params_sp));
- }
- } else {
- error = response.GetStatus();
- }
- } else {
- LLDB_LOG(log, "failed to send packet");
- error.SetErrorStringWithFormat("failed to send packet: '%s'",
- escaped_packet.GetData());
+ if (response.IsErrorResponse())
+ return response.GetStatus().ToError();
+ if (response.IsUnsupportedResponse())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "jLLDBTraceGetState is unsupported");
+ return std::string(response.Peek());
}
- return error;
+
+ LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to send packet: jLLDBTraceGetState '%s'",
+ escaped_packet.GetData());
}
-Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
- StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+llvm::Expected<std::vector<uint8_t>>
+GDBRemoteCommunicationClient::SendTraceGetBinaryData(
+ const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- Status error;
- StructuredData::Dictionary json_packet;
-
- json_packet.AddIntegerItem("traceid", uid);
- json_packet.AddIntegerItem("offset", offset);
- json_packet.AddIntegerItem("buffersize", buffer.size());
+ StreamGDBRemote escaped_packet;
+ escaped_packet.PutCString("jLLDBTraceGetBinaryData:");
- if (thread_id != LLDB_INVALID_THREAD_ID)
- json_packet.AddIntegerItem("threadid", thread_id);
+ std::string json_string;
+ llvm::raw_string_ostream os(json_string);
+ os << toJSON(request);
+ os.flush();
- StreamString json_string;
- json_packet.Dump(json_string, false);
+ escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
- packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
+ if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+ timeout) ==
GDBRemoteCommunication::PacketResult::Success) {
- if (response.IsNormalResponse()) {
- size_t filled_size = response.GetHexBytesAvail(buffer);
- buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
- } else {
- error = response.GetStatus();
- buffer = buffer.slice(buffer.size());
- }
- } else {
- LLDB_LOG(log, "failed to send packet");
- error.SetErrorStringWithFormat("failed to send packet: '%s'",
- packet.GetData());
- buffer = buffer.slice(buffer.size());
+ if (response.IsErrorResponse())
+ return response.GetStatus().ToError();
+ if (response.IsUnsupportedResponse())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "jLLDBTraceGetBinaryData is unsupported");
+ std::string data;
+ response.GetEscapedBinaryData(data);
+ return std::vector<uint8_t>(data.begin(), data.end());
}
- return error;
+ LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to send packet: jLLDBTraceGetBinaryData '%s'",
+ escaped_packet.GetData());
}
llvm::Optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(
- "qOffsets", response, /*send_async=*/false) != PacketResult::Success)
+ if (SendPacketAndWaitForResponse("qOffsets", response) !=
+ PacketResult::Success)
return llvm::None;
if (!response.IsNormalResponse())
return llvm::None;
@@ -3666,7 +3652,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo(
packet.PutStringAsRawHex8(triple);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
+ if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
PacketResult::Success)
return false;
@@ -3773,7 +3759,7 @@ GDBRemoteCommunicationClient::GetModulesInfo(
ScopedTimeout timeout(*this, std::chrono::seconds(10));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
+ if (SendPacketAndWaitForResponse(payload.GetString(), response) !=
PacketResult::Success ||
response.IsErrorResponse())
return llvm::None;
@@ -3832,7 +3818,7 @@ bool GDBRemoteCommunicationClient::ReadExtFeature(
<< "," << std::hex << size;
GDBRemoteCommunication::PacketResult res =
- SendPacketAndWaitForResponse(packet.str(), chunk, false);
+ SendPacketAndWaitForResponse(packet.str(), chunk);
if (res != GDBRemoteCommunication::PacketResult::Success) {
err.SetErrorString("Error sending $qXfer packet");
@@ -3921,7 +3907,7 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
bool first_qsymbol_query = true;
if (m_supports_qSymbol && !m_qSymbol_requests_done) {
- Lock lock(*this, false);
+ Lock lock(*this);
if (lock) {
StreamString packet;
packet.PutCString("qSymbol::");
@@ -4049,9 +4035,8 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
// Poll it now.
StringExtractorGDBRemote response;
- const bool send_async = false;
- if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
- send_async) == PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==
+ PacketResult::Success) {
m_supported_async_json_packets_sp =
StructuredData::ParseJSON(std::string(response.GetStringRef()));
if (m_supported_async_json_packets_sp &&
@@ -4095,7 +4080,7 @@ Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
StringExtractorGDBRemote response;
- auto send_status = SendPacketAndWaitForResponse(packet, response, false);
+ auto send_status = SendPacketAndWaitForResponse(packet, response);
if (send_status != GDBRemoteCommunication::PacketResult::Success)
return Status("Sending QPassSignals packet failed");
@@ -4134,10 +4119,8 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
stream.Flush();
// Send the packet.
- const bool send_async = false;
StringExtractorGDBRemote response;
- auto result =
- SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
+ auto result = SendPacketAndWaitForResponse(stream.GetString(), response);
if (result == PacketResult::Success) {
// We failed if the config result comes back other than OK.
if (strcmp(response.GetStringRef().data(), "OK") == 0) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index af3755fce774..1e1797c10dfc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -22,7 +22,7 @@
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/StructuredData.h"
-#include "lldb/Utility/TraceOptions.h"
+#include "lldb/Utility/TraceGDBRemotePackets.h"
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
#endif
@@ -49,6 +49,12 @@ inline bool operator==(const QOffsets &a, const QOffsets &b) {
}
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets);
+// A trivial struct used to return a pair of PID and TID.
+struct PidTid {
+ uint64_t pid;
+ uint64_t tid;
+};
+
class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
public:
GDBRemoteCommunicationClient();
@@ -275,6 +281,8 @@ public:
ArchSpec GetSystemArchitecture();
+ uint32_t GetAddressingBits();
+
bool GetHostname(std::string &s);
lldb::addr_t GetShlibInfoAddr();
@@ -319,7 +327,8 @@ public:
GDBStoppointType type, // Type of breakpoint or watchpoint
bool insert, // Insert or remove?
lldb::addr_t addr, // Address of breakpoint or watchpoint
- uint32_t length); // Byte Size of breakpoint or watchpoint
+ uint32_t length, // Byte Size of breakpoint or watchpoint
+ std::chrono::seconds interrupt_timeout); // Time to wait for an interrupt
bool SetNonStopMode(const bool enable);
@@ -334,9 +343,14 @@ public:
// and response times.
bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);
- bool SetCurrentThread(uint64_t tid);
+ llvm::Optional<PidTid>
+ SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op);
- bool SetCurrentThreadForRun(uint64_t tid);
+ bool SetCurrentThread(uint64_t tid,
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
+
+ bool SetCurrentThreadForRun(uint64_t tid,
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
bool GetQXferAuxvReadSupported();
@@ -366,6 +380,9 @@ public:
return m_supports_alloc_dealloc_memory;
}
+ std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
+ GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable);
+
size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable);
@@ -446,6 +463,14 @@ public:
bool GetSharedCacheInfoSupported();
+ bool GetMemoryTaggingSupported();
+
+ lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len,
+ int32_t type);
+
+ Status WriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
+ const std::vector<uint8_t> &tags);
+
/// Use qOffsets to query the offset used when relocating the target
/// executable. If successful, the returned structure will contain at least
/// one value in the offsets field.
@@ -505,59 +530,61 @@ public:
ConfigureRemoteStructuredData(ConstString type_name,
const StructuredData::ObjectSP &config_sp);
- lldb::user_id_t SendStartTracePacket(const TraceOptions &options,
- Status &error);
+ llvm::Expected<TraceSupportedResponse>
+ SendTraceSupported(std::chrono::seconds interrupt_timeout);
- Status SendStopTracePacket(lldb::user_id_t uid, lldb::tid_t thread_id);
+ llvm::Error SendTraceStart(const llvm::json::Value &request,
+ std::chrono::seconds interrupt_timeout);
- Status SendGetDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0);
+ llvm::Error SendTraceStop(const TraceStopRequest &request,
+ std::chrono::seconds interrupt_timeout);
- Status SendGetMetaDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0);
+ llvm::Expected<std::string>
+ SendTraceGetState(llvm::StringRef type,
+ std::chrono::seconds interrupt_timeout);
- Status SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options);
-
- llvm::Expected<TraceTypeInfo> SendGetSupportedTraceType();
+ llvm::Expected<std::vector<uint8_t>>
+ SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request,
+ std::chrono::seconds interrupt_timeout);
protected:
- LazyBool m_supports_not_sending_acks;
- LazyBool m_supports_thread_suffix;
- LazyBool m_supports_threads_in_stop_reply;
- LazyBool m_supports_vCont_all;
- LazyBool m_supports_vCont_any;
- LazyBool m_supports_vCont_c;
- LazyBool m_supports_vCont_C;
- LazyBool m_supports_vCont_s;
- LazyBool m_supports_vCont_S;
- LazyBool m_qHostInfo_is_valid;
- LazyBool m_curr_pid_is_valid;
- LazyBool m_qProcessInfo_is_valid;
- LazyBool m_qGDBServerVersion_is_valid;
- LazyBool m_supports_alloc_dealloc_memory;
- LazyBool m_supports_memory_region_info;
- LazyBool m_supports_watchpoint_support_info;
- LazyBool m_supports_detach_stay_stopped;
- LazyBool m_watchpoints_trigger_after_instruction;
- LazyBool m_attach_or_wait_reply;
- LazyBool m_prepare_for_reg_writing_reply;
- LazyBool m_supports_p;
- LazyBool m_supports_x;
- LazyBool m_avoid_g_packets;
- LazyBool m_supports_QSaveRegisterState;
- LazyBool m_supports_qXfer_auxv_read;
- LazyBool m_supports_qXfer_libraries_read;
- LazyBool m_supports_qXfer_libraries_svr4_read;
- LazyBool m_supports_qXfer_features_read;
- LazyBool m_supports_qXfer_memory_map_read;
- LazyBool m_supports_augmented_libraries_svr4_read;
- LazyBool m_supports_jThreadExtendedInfo;
- LazyBool m_supports_jLoadedDynamicLibrariesInfos;
- LazyBool m_supports_jGetSharedCacheInfo;
- LazyBool m_supports_QPassSignals;
- LazyBool m_supports_error_string_reply;
+ LazyBool m_supports_not_sending_acks = eLazyBoolCalculate;
+ LazyBool m_supports_thread_suffix = eLazyBoolCalculate;
+ LazyBool m_supports_threads_in_stop_reply = eLazyBoolCalculate;
+ LazyBool m_supports_vCont_all = eLazyBoolCalculate;
+ LazyBool m_supports_vCont_any = eLazyBoolCalculate;
+ LazyBool m_supports_vCont_c = eLazyBoolCalculate;
+ LazyBool m_supports_vCont_C = eLazyBoolCalculate;
+ LazyBool m_supports_vCont_s = eLazyBoolCalculate;
+ LazyBool m_supports_vCont_S = eLazyBoolCalculate;
+ LazyBool m_qHostInfo_is_valid = eLazyBoolCalculate;
+ LazyBool m_curr_pid_is_valid = eLazyBoolCalculate;
+ LazyBool m_qProcessInfo_is_valid = eLazyBoolCalculate;
+ LazyBool m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
+ LazyBool m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
+ LazyBool m_supports_memory_region_info = eLazyBoolCalculate;
+ LazyBool m_supports_watchpoint_support_info = eLazyBoolCalculate;
+ LazyBool m_supports_detach_stay_stopped = eLazyBoolCalculate;
+ LazyBool m_watchpoints_trigger_after_instruction = eLazyBoolCalculate;
+ LazyBool m_attach_or_wait_reply = eLazyBoolCalculate;
+ LazyBool m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
+ LazyBool m_supports_p = eLazyBoolCalculate;
+ LazyBool m_supports_x = eLazyBoolCalculate;
+ LazyBool m_avoid_g_packets = eLazyBoolCalculate;
+ LazyBool m_supports_QSaveRegisterState = eLazyBoolCalculate;
+ LazyBool m_supports_qXfer_auxv_read = eLazyBoolCalculate;
+ LazyBool m_supports_qXfer_libraries_read = eLazyBoolCalculate;
+ LazyBool m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
+ LazyBool m_supports_qXfer_features_read = eLazyBoolCalculate;
+ LazyBool m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
+ LazyBool m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
+ LazyBool m_supports_jThreadExtendedInfo = eLazyBoolCalculate;
+ LazyBool m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolCalculate;
+ LazyBool m_supports_jGetSharedCacheInfo = eLazyBoolCalculate;
+ LazyBool m_supports_QPassSignals = eLazyBoolCalculate;
+ LazyBool m_supports_error_string_reply = eLazyBoolCalculate;
+ LazyBool m_supports_multiprocess = eLazyBoolCalculate;
+ LazyBool m_supports_memory_tagging = eLazyBoolCalculate;
bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
m_supports_qUserName : 1, m_supports_qGroupName : 1,
@@ -568,13 +595,17 @@ protected:
m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1,
m_supports_jModulesInfo : 1;
- lldb::pid_t m_curr_pid;
- lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all
- // other operations
- lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for
- // continue, step, etc
+ /// Current gdb remote protocol process identifier for all other operations
+ lldb::pid_t m_curr_pid = LLDB_INVALID_PROCESS_ID;
+ /// Current gdb remote protocol process identifier for continue, step, etc
+ lldb::pid_t m_curr_pid_run = LLDB_INVALID_PROCESS_ID;
+ /// Current gdb remote protocol thread identifier for all other operations
+ lldb::tid_t m_curr_tid = LLDB_INVALID_THREAD_ID;
+ /// Current gdb remote protocol thread identifier for continue, step, etc
+ lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID;
- uint32_t m_num_supported_hardware_watchpoints;
+ uint32_t m_num_supported_hardware_watchpoints = 0;
+ uint32_t m_addressing_bits = 0;
ArchSpec m_host_arch;
ArchSpec m_process_arch;
@@ -585,17 +616,19 @@ protected:
std::string m_hostname;
std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if
// qGDBServerVersion is not supported
- uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if
- // qGDBServerVersion is not supported
+ uint32_t m_gdb_server_version =
+ UINT32_MAX; // from reply to qGDBServerVersion, zero if
+ // qGDBServerVersion is not supported
std::chrono::seconds m_default_packet_timeout;
- uint64_t m_max_packet_size; // as returned by qSupported
+ int m_target_vm_page_size = 0; // target system VM page size; 0 unspecified
+ uint64_t m_max_packet_size = 0; // as returned by qSupported
std::string m_qSupported_response; // the complete response to qSupported
- bool m_supported_async_json_packets_is_valid;
+ bool m_supported_async_json_packets_is_valid = false;
lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
std::vector<MemoryRegionInfo> m_qXfer_memory_map;
- bool m_qXfer_memory_map_loaded;
+ bool m_qXfer_memory_map_loaded = false;
bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
@@ -603,7 +636,8 @@ protected:
// Given the list of compression types that the remote debug stub can support,
// possibly enable compression if we find an encoding we can handle.
- void MaybeEnableCompression(std::vector<std::string> supported_compressions);
+ void MaybeEnableCompression(
+ llvm::ArrayRef<llvm::StringRef> supported_compressions);
bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
ProcessInstanceInfo &process_info);
@@ -612,7 +646,7 @@ protected:
PacketResult SendThreadSpecificPacketAndWaitForResponse(
lldb::tid_t tid, StreamString &&payload,
- StringExtractorGDBRemote &response, bool send_async);
+ StringExtractorGDBRemote &response);
Status SendGetTraceDataPacket(StreamGDBRemote &packet, lldb::user_id_t uid,
lldb::tid_t thread_id,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index 3984a45c3da1..d92c97e81659 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -19,13 +19,12 @@ using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
- : m_packets(), m_curr_idx(0), m_total_packet_count(0),
- m_dumped_to_log(false) {
+ : m_packets() {
if (size)
m_packets.resize(size);
}
-GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
+GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() = default;
void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
GDBRemotePacket::Type type,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index e783e59c3455..eda464a758e4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -74,9 +74,9 @@ private:
}
std::vector<GDBRemotePacket> m_packets;
- uint32_t m_curr_idx;
- uint32_t m_total_packet_count;
- mutable bool m_dumped_to_log;
+ uint32_t m_curr_idx = 0;
+ uint32_t m_total_packet_count = 0;
+ mutable bool m_dumped_to_log = false;
repro::PacketRecorder *m_recorder = nullptr;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
index 920327e7d0ab..c91d7cb5ac30 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <errno.h>
+#include <cerrno>
#include "lldb/Host/Config.h"
#include "llvm/ADT/ScopeExit.h"
@@ -74,7 +74,7 @@ GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
m_async_broadcaster(nullptr, "lldb.gdb-replay.async-broadcaster"),
m_async_listener_sp(
Listener::MakeListener("lldb.gdb-replay.async-listener")),
- m_async_thread_state_mutex(), m_skip_acks(false) {
+ m_async_thread_state_mutex() {
m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
"async thread continue");
m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
index c13e5ee0bf92..2f8770d0accf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
@@ -73,7 +73,7 @@ protected:
HostThread m_async_thread;
std::recursive_mutex m_async_thread_state_mutex;
- bool m_skip_acks;
+ bool m_skip_acks = false;
private:
GDBRemoteCommunicationReplayServer(
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 60548efc0f33..11cac9fa3a4d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <errno.h>
+#include <cerrno>
#include "lldb/Host/Config.h"
@@ -16,11 +16,13 @@
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "lldb/Utility/UnimplementedError.h"
+#include "llvm/Support/JSON.h"
#include <cstring>
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace llvm;
GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
const char *comm_name, const char *listener_name)
@@ -31,7 +33,7 @@ GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
bool &quit) { return this->Handle_QErrorStringEnable(packet); });
}
-GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
+GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() = default;
void GDBRemoteCommunicationServer::RegisterPacketHandler(
StringExtractorGDBRemote::ServerPacketType packet_type,
@@ -151,3 +153,21 @@ GDBRemoteCommunicationServer::SendOKResponse() {
bool GDBRemoteCommunicationServer::HandshakeWithClient() {
return GetAck() == PacketResult::Success;
}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) {
+ std::string json_string;
+ raw_string_ostream os(json_string);
+ os << value;
+ os.flush();
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(json_string.c_str(), json_string.size());
+ return SendPacketNoLock(escaped_response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendJSONResponse(Expected<json::Value> value) {
+ if (!value)
+ return SendErrorResponse(value.takeError());
+ return SendJSONResponse(*value);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index a1cf70f9cd1a..68448eae2b9f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -72,6 +72,13 @@ protected:
PacketResult SendOKResponse();
+ /// Serialize and send a JSON object response.
+ PacketResult SendJSONResponse(const llvm::json::Value &value);
+
+ /// Serialize and send a JSON object response, or respond with an error if the
+ /// input object is an \a llvm::Error.
+ PacketResult SendJSONResponse(llvm::Expected<llvm::json::Value> value);
+
private:
GDBRemoteCommunicationServer(const GDBRemoteCommunicationServer &) = delete;
const GDBRemoteCommunicationServer &
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 1ca0290eda13..b2b802552720 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -8,7 +8,7 @@
#include "GDBRemoteCommunicationServerCommon.h"
-#include <errno.h>
+#include <cerrno>
#ifdef __APPLE__
#include <TargetConditionals.h>
@@ -60,8 +60,7 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
const char *comm_name, const char *listener_name)
: GDBRemoteCommunicationServer(comm_name, listener_name),
m_process_launch_info(), m_process_launch_error(), m_proc_infos(),
- m_proc_infos_index(0), m_thread_suffix_supported(false),
- m_list_threads_in_stop_reply(false) {
+ m_proc_infos_index(0) {
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
&GDBRemoteCommunicationServerCommon::Handle_A);
RegisterMemberFunctionHandler(
@@ -86,9 +85,6 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
&GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
- &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
- RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_qEcho,
&GDBRemoteCommunicationServerCommon::Handle_qEcho);
RegisterMemberFunctionHandler(
@@ -134,9 +130,6 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
StringExtractorGDBRemote::eServerPacketType_qSupported,
&GDBRemoteCommunicationServerCommon::Handle_qSupported);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
- &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
- RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_qUserName,
&GDBRemoteCommunicationServerCommon::Handle_qUserName);
RegisterMemberFunctionHandler(
@@ -175,7 +168,8 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
}
// Destructor
-GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {}
+GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() =
+ default;
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
@@ -831,39 +825,10 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qSupported(
StringExtractorGDBRemote &packet) {
- StreamGDBRemote response;
-
- // Features common to lldb-platform and llgs.
- uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet
- // size--debugger can always use less
- response.Printf("PacketSize=%x", max_packet_size);
-
- response.PutCString(";QStartNoAckMode+");
- response.PutCString(";QThreadSuffixSupported+");
- response.PutCString(";QListThreadsInStopReply+");
- response.PutCString(";qEcho+");
- response.PutCString(";qXfer:features:read+");
-#if defined(__linux__) || defined(__NetBSD__) || defined(__FreeBSD__)
- response.PutCString(";QPassSignals+");
- response.PutCString(";qXfer:auxv:read+");
- response.PutCString(";qXfer:libraries-svr4:read+");
-#endif
-
- return SendPacketNoLock(response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported(
- StringExtractorGDBRemote &packet) {
- m_thread_suffix_supported = true;
- return SendOKResponse();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply(
- StringExtractorGDBRemote &packet) {
- m_list_threads_in_stop_reply = true;
- return SendOKResponse();
+ // Parse client-indicated features.
+ llvm::SmallVector<llvm::StringRef, 4> client_features;
+ packet.GetStringRef().split(client_features, ';');
+ return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";"));
}
GDBRemoteCommunication::PacketResult
@@ -1311,3 +1276,16 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path,
return matched_module_spec;
}
+
+std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures(
+ const llvm::ArrayRef<llvm::StringRef> client_features) {
+ // 128KBytes is a reasonable max packet size--debugger can always use less.
+ constexpr uint32_t max_packet_size = 128 * 1024;
+
+ // Features common to platform server and llgs.
+ return {
+ llvm::formatv("PacketSize={0}", max_packet_size),
+ "QStartNoAckMode+",
+ "qEcho+",
+ };
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index 0f933c09cbd4..ecd80923fcf0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -36,8 +36,6 @@ protected:
Status m_process_launch_error;
ProcessInstanceInfoList m_proc_infos;
uint32_t m_proc_infos_index;
- bool m_thread_suffix_supported;
- bool m_list_threads_in_stop_reply;
PacketResult Handle_A(StringExtractorGDBRemote &packet);
@@ -91,10 +89,6 @@ protected:
PacketResult Handle_qSupported(StringExtractorGDBRemote &packet);
- PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet);
-
- PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet);
-
PacketResult Handle_QSetDetachOnError(StringExtractorGDBRemote &packet);
PacketResult Handle_QStartNoAckMode(StringExtractorGDBRemote &packet);
@@ -145,6 +139,11 @@ protected:
virtual FileSpec FindModuleFile(const std::string &module_path,
const ArchSpec &arch);
+ // Process client_features (qSupported) and return an array of server features
+ // to be returned in response.
+ virtual std::vector<std::string>
+ HandleFeatures(llvm::ArrayRef<llvm::StringRef> client_features);
+
private:
ModuleSpec GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple);
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 62a09a2a432c..5e69b5793f9f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -6,13 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#include <errno.h>
+#include <cerrno>
#include "lldb/Host/Config.h"
#include <chrono>
#include <cstring>
+#include <limits>
#include <thread>
#include "GDBRemoteCommunicationServerLLGS.h"
@@ -70,6 +71,7 @@ GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
: GDBRemoteCommunicationServerCommon("gdb-remote.server",
"gdb-remote.server.rx_packet"),
m_mainloop(mainloop), m_process_factory(process_factory),
+ m_current_process(nullptr), m_continue_process(nullptr),
m_stdio_communication("process.stdio") {
RegisterPacketHandlers();
}
@@ -113,6 +115,12 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
&GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
+ &GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
+ &GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply);
+ RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
&GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
RegisterMemberFunctionHandler(
@@ -186,27 +194,32 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
&GDBRemoteCommunicationServerLLGS::Handle_QPassSignals);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_jTraceStart,
- &GDBRemoteCommunicationServerLLGS::Handle_jTraceStart);
+ StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupported,
+ &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_jTraceBufferRead,
- &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead);
+ StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStart,
+ &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_jTraceMetaRead,
- &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead);
+ StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStop,
+ &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_jTraceStop,
- &GDBRemoteCommunicationServerLLGS::Handle_jTraceStop);
+ StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetState,
+ &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
- &GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
- RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupportedType,
- &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType);
+ StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData,
+ &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
&GDBRemoteCommunicationServerLLGS::Handle_g);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qMemTags,
+ &GDBRemoteCommunicationServerLLGS::Handle_qMemTags);
+
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QMemTags,
+ &GDBRemoteCommunicationServerLLGS::Handle_QMemTags);
+
RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
[this](StringExtractorGDBRemote packet, Status &error,
bool &interrupt, bool &quit) {
@@ -245,15 +258,18 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
{
std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
- assert(!m_debugged_process_up && "lldb-server creating debugged "
- "process but one already exists");
+ assert(m_debugged_processes.empty() && "lldb-server creating debugged "
+ "process but one already exists");
auto process_or =
m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
if (!process_or)
return Status(process_or.takeError());
- m_debugged_process_up = std::move(*process_or);
+ m_continue_process = m_current_process = process_or->get();
+ m_debugged_processes[m_current_process->GetID()] = std::move(*process_or);
}
+ SetEnabledExtensions(*m_current_process);
+
// Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as
// needed. llgs local-process debugging may specify PTY paths, which will
// make these file actions non-null process launch -i/e/o will also make
@@ -266,10 +282,10 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
LLDB_LOG(log,
"pid = {0}: setting up stdout/stderr redirection via $O "
"gdb-remote commands",
- m_debugged_process_up->GetID());
+ m_current_process->GetID());
// Setup stdout/stderr mapping from inferior to $O
- auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
+ auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
if (terminal_fd >= 0) {
LLDB_LOGF(log,
"ProcessGDBRemoteCommunicationServerLLGS::%s setting "
@@ -288,12 +304,12 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
LLDB_LOG(log,
"pid = {0} skipping stdout/stderr redirection via $O: inferior "
"will communicate over client-provided file descriptors",
- m_debugged_process_up->GetID());
+ m_current_process->GetID());
}
printf("Launched '%s' as process %" PRIu64 "...\n",
m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
- m_debugged_process_up->GetID());
+ m_current_process->GetID());
return Status();
}
@@ -305,12 +321,11 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
// Before we try to attach, make sure we aren't already monitoring something
// else.
- if (m_debugged_process_up &&
- m_debugged_process_up->GetID() != LLDB_INVALID_PROCESS_ID)
+ if (!m_debugged_processes.empty())
return Status("cannot attach to process %" PRIu64
" when another process with pid %" PRIu64
" is being debugged.",
- pid, m_debugged_process_up->GetID());
+ pid, m_current_process->GetID());
// Try to attach.
auto process_or = m_process_factory.Attach(pid, *this, m_mainloop);
@@ -320,10 +335,12 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
status);
return status;
}
- m_debugged_process_up = std::move(*process_or);
+ m_continue_process = m_current_process = process_or->get();
+ m_debugged_processes[m_current_process->GetID()] = std::move(*process_or);
+ SetEnabledExtensions(*m_current_process);
// Setup stdout/stderr mapping from inferior.
- auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
+ auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
if (terminal_fd >= 0) {
LLDB_LOGF(log,
"ProcessGDBRemoteCommunicationServerLLGS::%s setting "
@@ -648,6 +665,14 @@ static const char *GetStopReasonString(StopReason stop_reason) {
return "exception";
case eStopReasonExec:
return "exec";
+ case eStopReasonProcessorTrace:
+ return "processor trace";
+ case eStopReasonFork:
+ return "fork";
+ case eStopReasonVFork:
+ return "vfork";
+ case eStopReasonVForkDone:
+ return "vforkdone";
case eStopReasonInstrumentation:
case eStopReasonInvalid:
case eStopReasonPlanComplete:
@@ -736,15 +761,15 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
// Ensure we have a debugged process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(50);
LLDB_LOG(log, "preparing packet for pid {0} tid {1}",
- m_debugged_process_up->GetID(), tid);
+ m_current_process->GetID(), tid);
// Ensure we can get info on the given thread.
- NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid);
if (!thread)
return SendErrorResponse(51);
@@ -767,7 +792,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
LLDB_LOG(
log,
"pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}",
- m_debugged_process_up->GetID(), tid, signum, int(tid_stop_info.reason),
+ m_current_process->GetID(), tid, signum, int(tid_stop_info.reason),
tid_stop_info.details.exception.type);
// Print the signal number.
@@ -805,9 +830,9 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
uint32_t thread_index = 0;
NativeThreadProtocol *listed_thread;
- for (listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ for (listed_thread = m_current_process->GetThreadAtIndex(thread_index);
listed_thread; ++thread_index,
- listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
+ listed_thread = m_current_process->GetThreadAtIndex(thread_index)) {
if (thread_index > 0)
response.PutChar(',');
response.Printf("%" PRIx64, listed_thread->GetID());
@@ -822,7 +847,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
if (thread_index > 1) {
const bool threads_with_valid_stop_info_only = true;
llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo(
- *m_debugged_process_up, threads_with_valid_stop_info_only);
+ *m_current_process, threads_with_valid_stop_info_only);
if (threads_info) {
response.PutCString("jstopinfo:");
StreamString unescaped_response;
@@ -832,7 +857,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
} else {
LLDB_LOG_ERROR(log, threads_info.takeError(),
"failed to prepare a jstopinfo field for pid {1}: {0}",
- m_debugged_process_up->GetID());
+ m_current_process->GetID());
}
}
@@ -840,8 +865,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutCString("thread-pcs");
char delimiter = ':';
for (NativeThreadProtocol *thread;
- (thread = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
- ++i) {
+ (thread = m_current_process->GetThreadAtIndex(i)) != nullptr; ++i) {
NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber(
@@ -924,6 +948,22 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
}
}
+ // Include child process PID/TID for forks.
+ if (tid_stop_info.reason == eStopReasonFork ||
+ tid_stop_info.reason == eStopReasonVFork) {
+ assert(bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::multiprocess));
+ if (tid_stop_info.reason == eStopReasonFork)
+ assert(bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::fork));
+ if (tid_stop_info.reason == eStopReasonVFork)
+ assert(bool(m_extensions_supported &
+ NativeProcessProtocol::Extension::vfork));
+ response.Printf("%s:p%" PRIx64 ".%" PRIx64 ";", reason_str,
+ tid_stop_info.details.fork.child_pid,
+ tid_stop_info.details.fork.child_tid);
+ }
+
return SendPacketNoLock(response.GetString());
}
@@ -1028,6 +1068,15 @@ void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) {
ClearProcessSpecificData();
}
+void GDBRemoteCommunicationServerLLGS::NewSubprocess(
+ NativeProcessProtocol *parent_process,
+ std::unique_ptr<NativeProcessProtocol> child_process) {
+ lldb::pid_t child_pid = child_process->GetID();
+ assert(child_pid != LLDB_INVALID_PROCESS_ID);
+ assert(m_debugged_processes.find(child_pid) == m_debugged_processes.end());
+ m_debugged_processes[child_pid] = std::move(child_process);
+}
+
void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
@@ -1170,266 +1219,110 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceStart(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported(
StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse(68);
-
- if (!packet.ConsumeFront("jTraceStart:"))
- return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
-
- TraceOptions options;
- uint64_t type = std::numeric_limits<uint64_t>::max();
- uint64_t buffersize = std::numeric_limits<uint64_t>::max();
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
-
- auto json_object = StructuredData::ParseJSON(packet.Peek());
-
- if (!json_object ||
- json_object->GetType() != lldb::eStructuredDataTypeDictionary)
- return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
-
- auto json_dict = json_object->GetAsDictionary();
-
- json_dict->GetValueForKeyAsInteger("metabuffersize", metabuffersize);
- options.setMetaDataBufferSize(metabuffersize);
- json_dict->GetValueForKeyAsInteger("buffersize", buffersize);
- options.setTraceBufferSize(buffersize);
-
- json_dict->GetValueForKeyAsInteger("type", type);
- options.setType(static_cast<lldb::TraceType>(type));
-
- json_dict->GetValueForKeyAsInteger("threadid", tid);
- options.setThreadID(tid);
-
- StructuredData::ObjectSP custom_params_sp =
- json_dict->GetValueForKey("params");
- if (custom_params_sp &&
- custom_params_sp->GetType() != lldb::eStructuredDataTypeDictionary)
- return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
-
- options.setTraceParams(
- std::static_pointer_cast<StructuredData::Dictionary>(custom_params_sp));
-
- if (buffersize == std::numeric_limits<uint64_t>::max() ||
- type != lldb::TraceType::eTraceTypeProcessorTrace) {
- LLDB_LOG(log, "Ill formed packet buffersize = {0} type = {1}", buffersize,
- type);
- return SendIllFormedResponse(packet, "JTrace:start: Ill formed packet ");
- }
-
- Status error;
- lldb::user_id_t uid = LLDB_INVALID_UID;
- uid = m_debugged_process_up->StartTrace(options, error);
- LLDB_LOG(log, "uid is {0} , error is {1}", uid, error.GetError());
- if (error.Fail())
- return SendErrorResponse(error);
+ // Fail if we don't have a current process.
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(Status("Process not running."));
- StreamGDBRemote response;
- response.Printf("%" PRIx64, uid);
- return SendPacketNoLock(response.GetString());
+ return SendJSONResponse(m_current_process->TraceSupported());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceStop(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse(68);
-
- if (!packet.ConsumeFront("jTraceStop:"))
- return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
-
- lldb::user_id_t uid = LLDB_INVALID_UID;
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
-
- auto json_object = StructuredData::ParseJSON(packet.Peek());
-
- if (!json_object ||
- json_object->GetType() != lldb::eStructuredDataTypeDictionary)
- return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
-
- auto json_dict = json_object->GetAsDictionary();
-
- if (!json_dict->GetValueForKeyAsInteger("traceid", uid))
- return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(Status("Process not running."));
- json_dict->GetValueForKeyAsInteger("threadid", tid);
+ packet.ConsumeFront("jLLDBTraceStop:");
+ Expected<TraceStopRequest> stop_request =
+ json::parse<TraceStopRequest>(packet.Peek(), "TraceStopRequest");
+ if (!stop_request)
+ return SendErrorResponse(stop_request.takeError());
- Status error = m_debugged_process_up->StopTrace(uid, tid);
-
- if (error.Fail())
- return SendErrorResponse(error);
+ if (Error err = m_current_process->TraceStop(*stop_request))
+ return SendErrorResponse(std::move(err));
return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(Status("Process not running."));
- llvm::Expected<TraceTypeInfo> supported_trace_type =
- m_debugged_process_up->GetSupportedTraceType();
- if (!supported_trace_type)
- return SendErrorResponse(supported_trace_type.takeError());
+ packet.ConsumeFront("jLLDBTraceStart:");
+ Expected<TraceStartRequest> request =
+ json::parse<TraceStartRequest>(packet.Peek(), "TraceStartRequest");
+ if (!request)
+ return SendErrorResponse(request.takeError());
- StreamGDBRemote escaped_response;
- StructuredData::Dictionary json_packet;
+ if (Error err = m_current_process->TraceStart(packet.Peek(), request->type))
+ return SendErrorResponse(std::move(err));
- json_packet.AddStringItem("name", supported_trace_type->name);
- json_packet.AddStringItem("description", supported_trace_type->description);
-
- StreamString json_string;
- json_packet.Dump(json_string, false);
- escaped_response.PutEscapedBytes(json_string.GetData(),
- json_string.GetSize());
- return SendPacketNoLock(escaped_response.GetString());
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse(68);
-
- if (!packet.ConsumeFront("jTraceConfigRead:"))
- return SendIllFormedResponse(packet,
- "jTraceConfigRead: Ill formed packet ");
-
- lldb::user_id_t uid = LLDB_INVALID_UID;
- lldb::tid_t threadid = LLDB_INVALID_THREAD_ID;
-
- auto json_object = StructuredData::ParseJSON(packet.Peek());
-
- if (!json_object ||
- json_object->GetType() != lldb::eStructuredDataTypeDictionary)
- return SendIllFormedResponse(packet,
- "jTraceConfigRead: Ill formed packet ");
-
- auto json_dict = json_object->GetAsDictionary();
-
- if (!json_dict->GetValueForKeyAsInteger("traceid", uid))
- return SendIllFormedResponse(packet,
- "jTraceConfigRead: Ill formed packet ");
-
- json_dict->GetValueForKeyAsInteger("threadid", threadid);
-
- TraceOptions options;
- StreamGDBRemote response;
-
- options.setThreadID(threadid);
- Status error = m_debugged_process_up->GetTraceConfig(uid, options);
-
- if (error.Fail())
- return SendErrorResponse(error);
-
- StreamGDBRemote escaped_response;
- StructuredData::Dictionary json_packet;
-
- json_packet.AddIntegerItem("type", options.getType());
- json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
- json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(Status("Process not running."));
- StructuredData::DictionarySP custom_params = options.getTraceParams();
- if (custom_params)
- json_packet.AddItem("params", custom_params);
+ packet.ConsumeFront("jLLDBTraceGetState:");
+ Expected<TraceGetStateRequest> request =
+ json::parse<TraceGetStateRequest>(packet.Peek(), "TraceGetStateRequest");
+ if (!request)
+ return SendErrorResponse(request.takeError());
- StreamString json_string;
- json_packet.Dump(json_string, false);
- escaped_response.PutEscapedBytes(json_string.GetData(),
- json_string.GetSize());
- return SendPacketNoLock(escaped_response.GetString());
+ return SendJSONResponse(m_current_process->TraceGetState(request->type));
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceRead(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse(68);
-
- enum PacketType { MetaData, BufferData };
- PacketType tracetype = MetaData;
-
- if (packet.ConsumeFront("jTraceBufferRead:"))
- tracetype = BufferData;
- else if (packet.ConsumeFront("jTraceMetaRead:"))
- tracetype = MetaData;
- else {
- return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
- }
-
- lldb::user_id_t uid = LLDB_INVALID_UID;
-
- uint64_t byte_count = std::numeric_limits<uint64_t>::max();
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- uint64_t offset = std::numeric_limits<uint64_t>::max();
-
- auto json_object = StructuredData::ParseJSON(packet.Peek());
-
- if (!json_object ||
- json_object->GetType() != lldb::eStructuredDataTypeDictionary)
- return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
-
- auto json_dict = json_object->GetAsDictionary();
-
- if (!json_dict->GetValueForKeyAsInteger("traceid", uid) ||
- !json_dict->GetValueForKeyAsInteger("offset", offset) ||
- !json_dict->GetValueForKeyAsInteger("buffersize", byte_count))
- return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
-
- json_dict->GetValueForKeyAsInteger("threadid", tid);
-
- // Allocate the response buffer.
- std::unique_ptr<uint8_t[]> buffer (new (std::nothrow) uint8_t[byte_count]);
- if (!buffer)
- return SendErrorResponse(0x78);
-
- StreamGDBRemote response;
- Status error;
- llvm::MutableArrayRef<uint8_t> buf(buffer.get(), byte_count);
-
- if (tracetype == BufferData)
- error = m_debugged_process_up->GetData(uid, tid, buf, offset);
- else if (tracetype == MetaData)
- error = m_debugged_process_up->GetMetaData(uid, tid, buf, offset);
-
- if (error.Fail())
- return SendErrorResponse(error);
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(Status("Process not running."));
- for (auto i : buf)
- response.PutHex8(i);
+ packet.ConsumeFront("jLLDBTraceGetBinaryData:");
+ llvm::Expected<TraceGetBinaryDataRequest> request =
+ llvm::json::parse<TraceGetBinaryDataRequest>(packet.Peek(),
+ "TraceGetBinaryDataRequest");
+ if (!request)
+ return SendErrorResponse(Status(request.takeError()));
- StreamGDBRemote escaped_response;
- escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
- return SendPacketNoLock(escaped_response.GetString());
+ if (Expected<std::vector<uint8_t>> bytes =
+ m_current_process->TraceGetBinaryData(*request)) {
+ StreamGDBRemote response;
+ response.PutEscapedBytes(bytes->data(), bytes->size());
+ return SendPacketNoLock(response.GetString());
+ } else
+ return SendErrorResponse(bytes.takeError());
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(68);
- lldb::pid_t pid = m_debugged_process_up->GetID();
+ lldb::pid_t pid = m_current_process->GetID();
if (pid == LLDB_INVALID_PROCESS_ID)
return SendErrorResponse(1);
@@ -1446,16 +1339,16 @@ GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(68);
// Make sure we set the current thread so g and p packets return the data the
// gdb will expect.
- lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
+ lldb::tid_t tid = m_current_process->GetCurrentThreadID();
SetCurrentThreadID(tid);
- NativeThreadProtocol *thread = m_debugged_process_up->GetCurrentThread();
+ NativeThreadProtocol *thread = m_current_process->GetCurrentThread();
if (!thread)
return SendErrorResponse(69);
@@ -1471,15 +1364,15 @@ GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
StopSTDIOForwarding();
- if (!m_debugged_process_up) {
+ if (!m_current_process) {
LLDB_LOG(log, "No debugged process found.");
return PacketResult::Success;
}
- Status error = m_debugged_process_up->Kill();
+ Status error = m_current_process->Kill();
if (error.Fail())
LLDB_LOG(log, "Failed to kill debugged process {0}: {1}",
- m_debugged_process_up->GetID(), error);
+ m_current_process->GetID(), error);
// No OK response for kill packet.
// return SendOKResponse ();
@@ -1521,12 +1414,26 @@ GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported(
+ StringExtractorGDBRemote &packet) {
+ m_thread_suffix_supported = true;
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply(
+ StringExtractorGDBRemote &packet) {
+ m_list_threads_in_stop_reply = true;
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
// Ensure we have a native process.
- if (!m_debugged_process_up) {
+ if (!m_continue_process) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s no debugged process "
"shared pointer",
@@ -1579,20 +1486,20 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
} else {
// Send the signal to the process since we weren't targeting a specific
// continue thread with the signal.
- error = m_debugged_process_up->Signal(signo);
+ error = m_continue_process->Signal(signo);
if (error.Fail()) {
LLDB_LOG(log, "failed to send signal for process {0}: {1}",
- m_debugged_process_up->GetID(), error);
+ m_continue_process->GetID(), error);
return SendErrorResponse(0x52);
}
}
// Resume the threads.
- error = m_debugged_process_up->Resume(resume_actions);
+ error = m_continue_process->Resume(resume_actions);
if (error.Fail()) {
LLDB_LOG(log, "failed to resume threads for process {0}: {1}",
- m_debugged_process_up->GetID(), error);
+ m_continue_process->GetID(), error);
return SendErrorResponse(0x38);
}
@@ -1617,7 +1524,7 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
}
// Ensure we have a native process.
- if (!m_debugged_process_up) {
+ if (!m_continue_process) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s no debugged process "
"shared pointer",
@@ -1629,14 +1536,14 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
ResumeActionList actions(StateType::eStateRunning,
LLDB_INVALID_SIGNAL_NUMBER);
- Status error = m_debugged_process_up->Resume(actions);
+ Status error = m_continue_process->Resume(actions);
if (error.Fail()) {
- LLDB_LOG(log, "c failed for process {0}: {1}",
- m_debugged_process_up->GetID(), error);
+ LLDB_LOG(log, "c failed for process {0}: {1}", m_continue_process->GetID(),
+ error);
return SendErrorResponse(GDBRemoteServerError::eErrorResume);
}
- LLDB_LOG(log, "continued process {0}", m_debugged_process_up->GetID());
+ LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
// No response required from continue.
return PacketResult::Success;
}
@@ -1679,7 +1586,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont(
}
// Ensure we have a native process.
- if (!m_debugged_process_up) {
+ if (!m_continue_process) {
LLDB_LOG(log, "no debugged process");
return SendErrorResponse(0x36);
}
@@ -1732,23 +1639,27 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont(
// Consume the separator.
packet.GetChar();
- thread_action.tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
- if (thread_action.tid == LLDB_INVALID_THREAD_ID)
- return SendIllFormedResponse(
- packet, "Could not parse thread number in vCont packet");
+ llvm::Expected<lldb::tid_t> tid_ret =
+ ReadTid(packet, /*allow_all=*/true, m_continue_process->GetID());
+ if (!tid_ret)
+ return SendErrorResponse(tid_ret.takeError());
+
+ thread_action.tid = tid_ret.get();
+ if (thread_action.tid == StringExtractorGDBRemote::AllThreads)
+ thread_action.tid = LLDB_INVALID_THREAD_ID;
}
thread_actions.Append(thread_action);
}
- Status error = m_debugged_process_up->Resume(thread_actions);
+ Status error = m_continue_process->Resume(thread_actions);
if (error.Fail()) {
LLDB_LOG(log, "vCont failed for process {0}: {1}",
- m_debugged_process_up->GetID(), error);
+ m_continue_process->GetID(), error);
return SendErrorResponse(GDBRemoteServerError::eErrorResume);
}
- LLDB_LOG(log, "continued process {0}", m_debugged_process_up->GetID());
+ LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
// No response required from vCont.
return PacketResult::Success;
}
@@ -1758,8 +1669,8 @@ void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) {
LLDB_LOG(log, "setting current thread id to {0}", tid);
m_current_tid = tid;
- if (m_debugged_process_up)
- m_debugged_process_up->SetCurrentThreadID(m_current_tid);
+ if (m_current_process)
+ m_current_process->SetCurrentThreadID(m_current_tid);
}
void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
@@ -1775,10 +1686,10 @@ GDBRemoteCommunicationServerLLGS::Handle_stop_reason(
// Handle the $? gdbremote command.
// If no process, indicate error
- if (!m_debugged_process_up)
+ if (!m_current_process)
return SendErrorResponse(02);
- return SendStopReasonForState(m_debugged_process_up->GetState());
+ return SendStopReasonForState(m_current_process->GetState());
}
GDBRemoteCommunication::PacketResult
@@ -1799,8 +1710,8 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
case eStateSuspended:
case eStateStopped:
case eStateCrashed: {
- assert(m_debugged_process_up != nullptr);
- lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
+ assert(m_current_process != nullptr);
+ lldb::tid_t tid = m_current_process->GetCurrentThreadID();
// Make sure we set the current thread so g and p packets return the data
// the gdb will expect.
SetCurrentThreadID(tid);
@@ -1810,11 +1721,11 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
case eStateInvalid:
case eStateUnloaded:
case eStateExited:
- return SendWResponse(m_debugged_process_up.get());
+ return SendWResponse(m_current_process);
default:
LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}",
- m_debugged_process_up->GetID(), process_state);
+ m_current_process->GetID(), process_state);
break;
}
@@ -1825,12 +1736,12 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(68);
// Ensure we have a thread.
- NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+ NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0);
if (!thread)
return SendErrorResponse(69);
@@ -1925,11 +1836,11 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOG(log, "no process ({0}), returning OK",
- m_debugged_process_up ? "invalid process id"
- : "null m_debugged_process_up");
+ m_current_process ? "invalid process id"
+ : "null m_current_process");
return SendOKResponse();
}
@@ -1940,9 +1851,9 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
NativeThreadProtocol *thread;
uint32_t thread_index;
for (thread_index = 0,
- thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ thread = m_current_process->GetThreadAtIndex(thread_index);
thread; ++thread_index,
- thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
+ thread = m_current_process->GetThreadAtIndex(thread_index)) {
LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
thread->GetID());
if (thread_index > 0)
@@ -2163,9 +2074,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Build the reginfos response.
StreamGDBRemote response;
- RegisterValue reg_value(
- makeArrayRef(reg_bytes, reg_size),
- m_debugged_process_up->GetArchitecture().GetByteOrder());
+ RegisterValue reg_value(makeArrayRef(reg_bytes, reg_size),
+ m_current_process->GetArchitecture().GetByteOrder());
Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
LLDB_LOGF(log,
@@ -2182,16 +2092,6 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- // Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- LLDB_LOGF(
- log,
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
- return SendErrorResponse(0x15);
- }
-
// Parse out which variant of $H is requested.
packet.SetFilePos(strlen("H"));
if (packet.GetBytesLeft() < 1) {
@@ -2203,11 +2103,14 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
}
const char h_variant = packet.GetChar();
+ NativeProcessProtocol *default_process;
switch (h_variant) {
case 'g':
+ default_process = m_current_process;
break;
case 'c':
+ default_process = m_continue_process;
break;
default:
@@ -2220,14 +2123,32 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
}
// Parse out the thread number.
- // FIXME return a parse success/fail value. All values are valid here.
- const lldb::tid_t tid =
- packet.GetHexMaxU64(false, std::numeric_limits<lldb::tid_t>::max());
+ auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
+ if (!pid_tid)
+ return SendErrorResponse(llvm::make_error<StringError>(
+ inconvertibleErrorCode(), "Malformed thread-id"));
+
+ lldb::pid_t pid = pid_tid->first;
+ lldb::tid_t tid = pid_tid->second;
+
+ if (pid == StringExtractorGDBRemote::AllProcesses)
+ return SendUnimplementedResponse("Selecting all processes not supported");
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(llvm::make_error<StringError>(
+ inconvertibleErrorCode(), "No current process and no PID provided"));
+
+ // Check the process ID and find respective process instance.
+ auto new_process_it = m_debugged_processes.find(pid);
+ if (new_process_it == m_debugged_processes.end())
+ return SendErrorResponse(llvm::make_error<StringError>(
+ inconvertibleErrorCode(),
+ llvm::formatv("No process with PID {0} debugged", pid)));
// Ensure we have the given thread when not specifying -1 (all threads) or 0
// (any thread).
if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
- NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ NativeThreadProtocol *thread = new_process_it->second->GetThreadByID(tid);
if (!thread) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
@@ -2237,13 +2158,15 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
}
}
- // Now switch the given thread type.
+ // Now switch the given process and thread type.
switch (h_variant) {
case 'g':
+ m_current_process = new_process_it->second.get();
SetCurrentThreadID(tid);
break;
case 'c':
+ m_continue_process = new_process_it->second.get();
SetContinueThreadID(tid);
break;
@@ -2261,8 +2184,8 @@ GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2297,21 +2220,21 @@ GDBRemoteCommunicationServerLLGS::Handle_interrupt(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOG(log, "failed, no process available");
return SendErrorResponse(0x15);
}
// Interrupt the process.
- Status error = m_debugged_process_up->Interrupt();
+ Status error = m_current_process->Interrupt();
if (error.Fail()) {
- LLDB_LOG(log, "failed for process {0}: {1}", m_debugged_process_up->GetID(),
+ LLDB_LOG(log, "failed for process {0}: {1}", m_current_process->GetID(),
error);
return SendErrorResponse(GDBRemoteServerError::eErrorResume);
}
- LLDB_LOG(log, "stopped process {0}", m_debugged_process_up->GetID());
+ LLDB_LOG(log, "stopped process {0}", m_current_process->GetID());
// No response required from stop all.
return PacketResult::Success;
@@ -2322,8 +2245,8 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2365,13 +2288,13 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
// Retrieve the process memory.
size_t bytes_read = 0;
- Status error = m_debugged_process_up->ReadMemoryWithoutTrap(
+ Status error = m_current_process->ReadMemoryWithoutTrap(
read_addr, &buf[0], byte_count, bytes_read);
if (error.Fail()) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
" mem 0x%" PRIx64 ": failed to read. Error: %s",
- __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
+ __FUNCTION__, m_current_process->GetID(), read_addr,
error.AsCString());
return SendErrorResponse(0x08);
}
@@ -2380,8 +2303,7 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
" mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
- __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
- byte_count);
+ __FUNCTION__, m_current_process->GetID(), read_addr, byte_count);
return SendErrorResponse(0x08);
}
@@ -2403,8 +2325,8 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2439,8 +2361,7 @@ GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) {
}
}
- llvm::Expected<addr_t> addr =
- m_debugged_process_up->AllocateMemory(size, perms);
+ llvm::Expected<addr_t> addr = m_current_process->AllocateMemory(size, perms);
if (!addr)
return SendErrorResponse(addr.takeError());
@@ -2453,8 +2374,8 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2471,7 +2392,7 @@ GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) {
if (addr == LLDB_INVALID_ADDRESS)
return SendIllFormedResponse(packet, "Address not valid");
- if (llvm::Error Err = m_debugged_process_up->DeallocateMemory(addr))
+ if (llvm::Error Err = m_current_process->DeallocateMemory(addr))
return SendErrorResponse(std::move(Err));
return SendOKResponse();
@@ -2481,8 +2402,8 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2531,8 +2452,7 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
LLDB_LOG(log,
"pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} "
"to convert.",
- m_debugged_process_up->GetID(), write_addr, byte_count,
- convert_count);
+ m_current_process->GetID(), write_addr, byte_count, convert_count);
return SendIllFormedResponse(packet, "M content byte length specified did "
"not match hex-encoded content "
"length");
@@ -2540,17 +2460,17 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
// Write the process memory.
size_t bytes_written = 0;
- Status error = m_debugged_process_up->WriteMemory(write_addr, &buf[0],
- byte_count, bytes_written);
+ Status error = m_current_process->WriteMemory(write_addr, &buf[0], byte_count,
+ bytes_written);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} mem {1:x}: failed to write. Error: {2}",
- m_debugged_process_up->GetID(), write_addr, error);
+ m_current_process->GetID(), write_addr, error);
return SendErrorResponse(0x09);
}
if (bytes_written == 0) {
LLDB_LOG(log, "pid {0} mem {1:x}: wrote 0 of {2} requested bytes",
- m_debugged_process_up->GetID(), write_addr, byte_count);
+ m_current_process->GetID(), write_addr, byte_count);
return SendErrorResponse(0x09);
}
@@ -2569,8 +2489,8 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
// Ensure we have a process running; otherwise, we can't figure this out
// since we won't have a NativeProcessProtocol.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2580,8 +2500,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
// Test if we can get any region back when asking for the region around NULL.
MemoryRegionInfo region_info;
- const Status error =
- m_debugged_process_up->GetMemoryRegionInfo(0, region_info);
+ const Status error = m_current_process->GetMemoryRegionInfo(0, region_info);
if (error.Fail()) {
// We don't support memory region info collection for this
// NativeProcessProtocol.
@@ -2597,8 +2516,8 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
// Ensure we have a process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2619,7 +2538,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
// Get the memory region info for the target address.
MemoryRegionInfo region_info;
const Status error =
- m_debugged_process_up->GetMemoryRegionInfo(read_addr, region_info);
+ m_current_process->GetMemoryRegionInfo(read_addr, region_info);
if (error.Fail()) {
// Return the error message.
@@ -2674,8 +2593,8 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
// Ensure we have a process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
LLDB_LOG(log, "failed, no process available");
return SendErrorResponse(0x15);
@@ -2745,22 +2664,22 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
if (want_breakpoint) {
// Try to set the breakpoint.
const Status error =
- m_debugged_process_up->SetBreakpoint(addr, size, want_hardware);
+ m_current_process->SetBreakpoint(addr, size, want_hardware);
if (error.Success())
return SendOKResponse();
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}",
- m_debugged_process_up->GetID(), error);
+ m_current_process->GetID(), error);
return SendErrorResponse(0x09);
} else {
// Try to set the watchpoint.
- const Status error = m_debugged_process_up->SetWatchpoint(
+ const Status error = m_current_process->SetWatchpoint(
addr, size, watch_flags, want_hardware);
if (error.Success())
return SendOKResponse();
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}",
- m_debugged_process_up->GetID(), error);
+ m_current_process->GetID(), error);
return SendErrorResponse(0x09);
}
}
@@ -2768,8 +2687,8 @@ GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
// Ensure we have a process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
LLDB_LOG(log, "failed, no process available");
return SendErrorResponse(0x15);
@@ -2833,21 +2752,21 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
if (want_breakpoint) {
// Try to clear the breakpoint.
const Status error =
- m_debugged_process_up->RemoveBreakpoint(addr, want_hardware);
+ m_current_process->RemoveBreakpoint(addr, want_hardware);
if (error.Success())
return SendOKResponse();
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}",
- m_debugged_process_up->GetID(), error);
+ m_current_process->GetID(), error);
return SendErrorResponse(0x09);
} else {
// Try to clear the watchpoint.
- const Status error = m_debugged_process_up->RemoveWatchpoint(addr);
+ const Status error = m_current_process->RemoveWatchpoint(addr);
if (error.Success())
return SendOKResponse();
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}",
- m_debugged_process_up->GetID(), error);
+ m_current_process->GetID(), error);
return SendErrorResponse(0x09);
}
}
@@ -2857,8 +2776,8 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
// Ensure we have a process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_continue_process ||
+ (m_continue_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
LLDB_LOGF(
log,
"GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2876,7 +2795,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
// Double check that we have such a thread.
// TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
- NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ NativeThreadProtocol *thread = m_continue_process->GetThreadByID(tid);
if (!thread)
return SendErrorResponse(0x33);
@@ -2889,12 +2808,12 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
// All other threads stop while we're single stepping a thread.
actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
- Status error = m_debugged_process_up->Resume(actions);
+ Status error = m_continue_process->Resume(actions);
if (error.Fail()) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
" tid %" PRIu64 " Resume() failed with error: %s",
- __FUNCTION__, m_debugged_process_up->GetID(), tid,
+ __FUNCTION__, m_continue_process->GetID(), tid,
error.AsCString());
return SendErrorResponse(0x49);
}
@@ -2906,7 +2825,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
// Ensure we have a thread.
- NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+ NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0);
if (!thread)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"No thread available");
@@ -2921,7 +2840,7 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
response.Printf("<target version=\"1.0\">");
response.Printf("<architecture>%s</architecture>",
- m_debugged_process_up->GetArchitecture()
+ m_current_process->GetArchitecture()
.GetTriple()
.getArchName()
.str()
@@ -3010,22 +2929,22 @@ llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
llvm::StringRef annex) {
// Make sure we have a valid process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"No process available");
}
if (object == "auxv") {
// Grab the auxv data.
- auto buffer_or_error = m_debugged_process_up->GetAuxvData();
+ auto buffer_or_error = m_current_process->GetAuxvData();
if (!buffer_or_error)
return llvm::errorCodeToError(buffer_or_error.getError());
return std::move(*buffer_or_error);
}
if (object == "libraries-svr4") {
- auto library_list = m_debugged_process_up->GetLoadedSVR4Libraries();
+ auto library_list = m_current_process->GetLoadedSVR4Libraries();
if (!library_list)
return library_list.takeError();
@@ -3148,7 +3067,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
Status error = reg_context.ReadAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to save all register values: {1}",
- m_debugged_process_up->GetID(), error);
+ m_current_process->GetID(), error);
return SendErrorResponse(0x75);
}
@@ -3211,7 +3130,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
if (it == m_saved_registers_map.end()) {
LLDB_LOG(log,
"pid {0} does not have a register set save buffer for id {1}",
- m_debugged_process_up->GetID(), save_id);
+ m_current_process->GetID(), save_id);
return SendErrorResponse(0x77);
}
register_data_sp = it->second;
@@ -3223,7 +3142,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
Status error = reg_context.WriteAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to restore all register values: {1}",
- m_debugged_process_up->GetID(), error);
+ m_current_process->GetID(), error);
return SendErrorResponse(0x77);
}
@@ -3263,7 +3182,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
}
// Notify we attached by sending a stop packet.
- return SendStopReasonForState(m_debugged_process_up->GetState());
+ return SendStopReasonForState(m_current_process->GetState());
}
GDBRemoteCommunication::PacketResult
@@ -3293,7 +3212,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
}
// Notify we attached by sending a stop packet.
- return SendStopReasonForState(m_debugged_process_up->GetState());
+ return SendStopReasonForState(m_current_process->GetState());
}
GDBRemoteCommunication::PacketResult
@@ -3329,25 +3248,13 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait(
}
// Notify we attached by sending a stop packet.
- return SendStopReasonForState(m_debugged_process_up->GetState());
+ return SendStopReasonForState(m_current_process->GetState());
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
StopSTDIOForwarding();
- // Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- LLDB_LOGF(
- log,
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
- return SendErrorResponse(0x15);
- }
-
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
// Consume the ';' after D.
@@ -3362,19 +3269,32 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
return SendIllFormedResponse(packet, "D failed to parse the process id");
}
- if (pid != LLDB_INVALID_PROCESS_ID && m_debugged_process_up->GetID() != pid) {
- return SendIllFormedResponse(packet, "Invalid pid");
- }
-
- const Status error = m_debugged_process_up->Detach();
- if (error.Fail()) {
- LLDB_LOGF(log,
- "GDBRemoteCommunicationServerLLGS::%s failed to detach from "
- "pid %" PRIu64 ": %s\n",
- __FUNCTION__, m_debugged_process_up->GetID(), error.AsCString());
- return SendErrorResponse(0x01);
+ // Detach forked children if their PID was specified *or* no PID was requested
+ // (i.e. detach-all packet).
+ llvm::Error detach_error = llvm::Error::success();
+ bool detached = false;
+ for (auto it = m_debugged_processes.begin();
+ it != m_debugged_processes.end();) {
+ if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) {
+ if (llvm::Error e = it->second->Detach().ToError())
+ detach_error = llvm::joinErrors(std::move(detach_error), std::move(e));
+ else {
+ if (it->second.get() == m_current_process)
+ m_current_process = nullptr;
+ if (it->second.get() == m_continue_process)
+ m_continue_process = nullptr;
+ it = m_debugged_processes.erase(it);
+ detached = true;
+ continue;
+ }
+ }
+ ++it;
}
+ if (detach_error)
+ return SendErrorResponse(std::move(detach_error));
+ if (!detached)
+ return SendErrorResponse(Status("PID %" PRIu64 " not traced", pid));
return SendOKResponse();
}
@@ -3384,7 +3304,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
packet.SetFilePos(strlen("qThreadStopInfo"));
- const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+ const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
if (tid == LLDB_INVALID_THREAD_ID) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s failed, could not "
@@ -3401,19 +3321,19 @@ GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
// Ensure we have a debugged process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(50);
- LLDB_LOG(log, "preparing packet for pid {0}", m_debugged_process_up->GetID());
+ LLDB_LOG(log, "preparing packet for pid {0}", m_current_process->GetID());
StreamString response;
const bool threads_with_valid_stop_info_only = false;
- llvm::Expected<json::Value> threads_info = GetJSONThreadsInfo(
- *m_debugged_process_up, threads_with_valid_stop_info_only);
+ llvm::Expected<json::Value> threads_info =
+ GetJSONThreadsInfo(*m_current_process, threads_with_valid_stop_info_only);
if (!threads_info) {
LLDB_LOG_ERROR(log, threads_info.takeError(),
"failed to prepare a packet for pid {1}: {0}",
- m_debugged_process_up->GetID());
+ m_current_process->GetID());
return SendErrorResponse(52);
}
@@ -3427,8 +3347,8 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
+ if (!m_current_process ||
+ m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
return SendErrorResponse(68);
packet.SetFilePos(strlen("qWatchpointSupportInfo"));
@@ -3437,7 +3357,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo(
if (packet.GetChar() != ':')
return SendErrorResponse(67);
- auto hw_debug_cap = m_debugged_process_up->GetHardwareDebugSupportInfo();
+ auto hw_debug_cap = m_current_process->GetHardwareDebugSupportInfo();
StreamGDBRemote response;
if (hw_debug_cap == llvm::None)
@@ -3452,8 +3372,8 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
- if (!m_debugged_process_up ||
- m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
+ if (!m_current_process ||
+ m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
return SendErrorResponse(67);
packet.SetFilePos(strlen("qFileLoadAddress:"));
@@ -3465,7 +3385,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress(
lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
Status error =
- m_debugged_process_up->GetFileLoadAddress(file_name, file_load_address);
+ m_current_process->GetFileLoadAddress(file_name, file_load_address);
if (error.Fail())
return SendErrorResponse(69);
@@ -3501,16 +3421,169 @@ GDBRemoteCommunicationServerLLGS::Handle_QPassSignals(
}
// Fail if we don't have a current process.
- if (!m_debugged_process_up)
+ if (!m_current_process)
return SendErrorResponse(68);
- Status error = m_debugged_process_up->IgnoreSignals(signals);
+ Status error = m_current_process->IgnoreSignals(signals);
if (error.Fail())
return SendErrorResponse(69);
return SendOKResponse();
}
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qMemTags(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Ensure we have a process.
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(1);
+ }
+
+ // We are expecting
+ // qMemTags:<hex address>,<hex length>:<hex type>
+
+ // Address
+ packet.SetFilePos(strlen("qMemTags:"));
+ const char *current_char = packet.Peek();
+ if (!current_char || *current_char == ',')
+ return SendIllFormedResponse(packet, "Missing address in qMemTags packet");
+ const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+ // Length
+ char previous_char = packet.GetChar();
+ current_char = packet.Peek();
+ // If we don't have a separator or the length field is empty
+ if (previous_char != ',' || (current_char && *current_char == ':'))
+ return SendIllFormedResponse(packet,
+ "Invalid addr,length pair in qMemTags packet");
+
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "Too short qMemtags: packet (looking for length)");
+ const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+ // Type
+ const char *invalid_type_err = "Invalid type field in qMemTags: packet";
+ if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
+ return SendIllFormedResponse(packet, invalid_type_err);
+
+ int32_t type =
+ packet.GetS32(std::numeric_limits<int32_t>::max(), /*base=*/16);
+ if (type == std::numeric_limits<int32_t>::max() ||
+ // To catch inputs like "123aardvark" that will parse but clearly aren't
+ // valid in this case.
+ packet.GetBytesLeft()) {
+ return SendIllFormedResponse(packet, invalid_type_err);
+ }
+
+ StreamGDBRemote response;
+ std::vector<uint8_t> tags;
+ Status error = m_current_process->ReadMemoryTags(type, addr, length, tags);
+ if (error.Fail())
+ return SendErrorResponse(1);
+
+ // This m is here in case we want to support multi part replies in the future.
+ // In the same manner as qfThreadInfo/qsThreadInfo.
+ response.PutChar('m');
+ response.PutBytesAsRawHex8(tags.data(), tags.size());
+ return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QMemTags(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Ensure we have a process.
+ if (!m_current_process ||
+ (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(1);
+ }
+
+ // We are expecting
+ // QMemTags:<hex address>,<hex length>:<hex type>:<tags as hex bytes>
+
+ // Address
+ packet.SetFilePos(strlen("QMemTags:"));
+ const char *current_char = packet.Peek();
+ if (!current_char || *current_char == ',')
+ return SendIllFormedResponse(packet, "Missing address in QMemTags packet");
+ const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+ // Length
+ char previous_char = packet.GetChar();
+ current_char = packet.Peek();
+ // If we don't have a separator or the length field is empty
+ if (previous_char != ',' || (current_char && *current_char == ':'))
+ return SendIllFormedResponse(packet,
+ "Invalid addr,length pair in QMemTags packet");
+
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "Too short QMemtags: packet (looking for length)");
+ const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+ // Type
+ const char *invalid_type_err = "Invalid type field in QMemTags: packet";
+ if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
+ return SendIllFormedResponse(packet, invalid_type_err);
+
+ // Our GetU64 uses strtoull which allows leading +/-, we don't want that.
+ const char *first_type_char = packet.Peek();
+ if (first_type_char && (*first_type_char == '+' || *first_type_char == '-'))
+ return SendIllFormedResponse(packet, invalid_type_err);
+
+ // The type is a signed integer but is in the packet as its raw bytes.
+ // So parse first as unsigned then cast to signed later.
+ // We extract to 64 bit, even though we only expect 32, so that we've
+ // got some invalid value we can check for.
+ uint64_t raw_type =
+ packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16);
+ if (raw_type > std::numeric_limits<uint32_t>::max())
+ return SendIllFormedResponse(packet, invalid_type_err);
+ int32_t type = static_cast<int32_t>(raw_type);
+
+ // Tag data
+ if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
+ return SendIllFormedResponse(packet,
+ "Missing tag data in QMemTags: packet");
+
+ // Must be 2 chars per byte
+ const char *invalid_data_err = "Invalid tag data in QMemTags: packet";
+ if (packet.GetBytesLeft() % 2)
+ return SendIllFormedResponse(packet, invalid_data_err);
+
+ // This is bytes here and is unpacked into target specific tags later
+ // We cannot assume that number of bytes == length here because the server
+ // can repeat tags to fill a given range.
+ std::vector<uint8_t> tag_data;
+ // Zero length writes will not have any tag data
+ // (but we pass them on because it will still check that tagging is enabled)
+ if (packet.GetBytesLeft()) {
+ size_t byte_count = packet.GetBytesLeft() / 2;
+ tag_data.resize(byte_count);
+ size_t converted_bytes = packet.GetHexBytes(tag_data, 0);
+ if (converted_bytes != byte_count) {
+ return SendIllFormedResponse(packet, invalid_data_err);
+ }
+ }
+
+ Status status =
+ m_current_process->WriteMemoryTags(type, addr, length, tag_data);
+ return status.Success() ? SendOKResponse() : SendErrorResponse(1);
+}
+
void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -3539,8 +3612,8 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
StringExtractorGDBRemote &packet) {
// We have no thread if we don't have a process.
- if (!m_debugged_process_up ||
- m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
+ if (!m_current_process ||
+ m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
return nullptr;
// If the client hasn't asked for thread suffix support, there will not be a
@@ -3551,9 +3624,9 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
return nullptr;
else if (current_tid == 0) {
// Pick a thread.
- return m_debugged_process_up->GetThreadAtIndex(0);
+ return m_current_process->GetThreadAtIndex(0);
} else
- return m_debugged_process_up->GetThreadByID(current_tid);
+ return m_current_process->GetThreadByID(current_tid);
}
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
@@ -3583,7 +3656,7 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
if (tid != 0)
- return m_debugged_process_up->GetThreadByID(tid);
+ return m_current_process->GetThreadByID(tid);
return nullptr;
}
@@ -3593,9 +3666,9 @@ lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
// Use whatever the debug process says is the current thread id since the
// protocol either didn't specify or specified we want any/all threads
// marked as the current thread.
- if (!m_debugged_process_up)
+ if (!m_current_process)
return LLDB_INVALID_THREAD_ID;
- return m_debugged_process_up->GetCurrentThreadID();
+ return m_current_process->GetCurrentThreadID();
}
// Use the specific current thread id set by the gdb remote protocol.
return m_current_tid;
@@ -3616,9 +3689,9 @@ void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() {
FileSpec
GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
const ArchSpec &arch) {
- if (m_debugged_process_up) {
+ if (m_current_process) {
FileSpec file_spec;
- if (m_debugged_process_up
+ if (m_current_process
->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
.Success()) {
if (FileSystem::Instance().Exists(file_spec))
@@ -3653,3 +3726,93 @@ std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue(
}
return result;
}
+
+llvm::Expected<lldb::tid_t> GDBRemoteCommunicationServerLLGS::ReadTid(
+ StringExtractorGDBRemote &packet, bool allow_all, lldb::pid_t default_pid) {
+ assert(m_current_process);
+ assert(m_current_process->GetID() != LLDB_INVALID_PROCESS_ID);
+
+ auto pid_tid = packet.GetPidTid(default_pid);
+ if (!pid_tid)
+ return llvm::make_error<StringError>(inconvertibleErrorCode(),
+ "Malformed thread-id");
+
+ lldb::pid_t pid = pid_tid->first;
+ lldb::tid_t tid = pid_tid->second;
+
+ if (!allow_all && pid == StringExtractorGDBRemote::AllProcesses)
+ return llvm::make_error<StringError>(
+ inconvertibleErrorCode(),
+ llvm::formatv("PID value {0} not allowed", pid == 0 ? 0 : -1));
+
+ if (!allow_all && tid == StringExtractorGDBRemote::AllThreads)
+ return llvm::make_error<StringError>(
+ inconvertibleErrorCode(),
+ llvm::formatv("TID value {0} not allowed", tid == 0 ? 0 : -1));
+
+ if (pid != StringExtractorGDBRemote::AllProcesses) {
+ if (pid != m_current_process->GetID())
+ return llvm::make_error<StringError>(
+ inconvertibleErrorCode(), llvm::formatv("PID {0} not debugged", pid));
+ }
+
+ return tid;
+}
+
+std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
+ const llvm::ArrayRef<llvm::StringRef> client_features) {
+ std::vector<std::string> ret =
+ GDBRemoteCommunicationServerCommon::HandleFeatures(client_features);
+ ret.insert(ret.end(), {
+ "QThreadSuffixSupported+",
+ "QListThreadsInStopReply+",
+ "qXfer:features:read+",
+ });
+
+ // report server-only features
+ using Extension = NativeProcessProtocol::Extension;
+ Extension plugin_features = m_process_factory.GetSupportedExtensions();
+ if (bool(plugin_features & Extension::pass_signals))
+ ret.push_back("QPassSignals+");
+ if (bool(plugin_features & Extension::auxv))
+ ret.push_back("qXfer:auxv:read+");
+ if (bool(plugin_features & Extension::libraries_svr4))
+ ret.push_back("qXfer:libraries-svr4:read+");
+ if (bool(plugin_features & Extension::memory_tagging))
+ ret.push_back("memory-tagging+");
+
+ // check for client features
+ m_extensions_supported = {};
+ for (llvm::StringRef x : client_features)
+ m_extensions_supported |=
+ llvm::StringSwitch<Extension>(x)
+ .Case("multiprocess+", Extension::multiprocess)
+ .Case("fork-events+", Extension::fork)
+ .Case("vfork-events+", Extension::vfork)
+ .Default({});
+
+ m_extensions_supported &= plugin_features;
+
+ // fork & vfork require multiprocess
+ if (!bool(m_extensions_supported & Extension::multiprocess))
+ m_extensions_supported &= ~(Extension::fork | Extension::vfork);
+
+ // report only if actually supported
+ if (bool(m_extensions_supported & Extension::multiprocess))
+ ret.push_back("multiprocess+");
+ if (bool(m_extensions_supported & Extension::fork))
+ ret.push_back("fork-events+");
+ if (bool(m_extensions_supported & Extension::vfork))
+ ret.push_back("vfork-events+");
+
+ for (auto &x : m_debugged_processes)
+ SetEnabledExtensions(*x.second);
+ return ret;
+}
+
+void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions(
+ NativeProcessProtocol &process) {
+ NativeProcessProtocol::Extension flags = m_extensions_supported;
+ assert(!bool(flags & ~m_process_factory.GetSupportedExtensions()));
+ process.SetEnabledExtensions(flags);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index c51139924559..04d0605fe420 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -78,6 +78,10 @@ public:
void DidExec(NativeProcessProtocol *process) override;
+ void
+ NewSubprocess(NativeProcessProtocol *parent_process,
+ std::unique_ptr<NativeProcessProtocol> child_process) override;
+
Status InitializeConnection(std::unique_ptr<Connection> connection);
protected:
@@ -86,8 +90,11 @@ protected:
const NativeProcessProtocol::Factory &m_process_factory;
lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID;
lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID;
+ NativeProcessProtocol *m_current_process;
+ NativeProcessProtocol *m_continue_process;
std::recursive_mutex m_debugged_process_mutex;
- std::unique_ptr<NativeProcessProtocol> m_debugged_process_up;
+ std::unordered_map<lldb::pid_t, std::unique_ptr<NativeProcessProtocol>>
+ m_debugged_processes;
Communication m_stdio_communication;
MainLoop::ReadHandleUP m_stdio_handle_up;
@@ -98,6 +105,10 @@ protected:
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
uint32_t m_next_saved_registers_id = 1;
bool m_handshake_completed = false;
+ bool m_thread_suffix_supported = false;
+ bool m_list_threads_in_stop_reply = false;
+
+ NativeProcessProtocol::Extension m_extensions_supported = {};
PacketResult SendONotification(const char *buffer, uint32_t len);
@@ -119,6 +130,10 @@ protected:
PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
+ PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet);
+
PacketResult Handle_C(StringExtractorGDBRemote &packet);
PacketResult Handle_c(StringExtractorGDBRemote &packet);
@@ -167,15 +182,15 @@ protected:
PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet);
- PacketResult Handle_jTraceStart(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jLLDBTraceSupported(StringExtractorGDBRemote &packet);
- PacketResult Handle_jTraceRead(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jLLDBTraceStart(StringExtractorGDBRemote &packet);
- PacketResult Handle_jTraceStop(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jLLDBTraceStop(StringExtractorGDBRemote &packet);
- PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jLLDBTraceGetState(StringExtractorGDBRemote &packet);
- PacketResult Handle_jLLDBTraceSupportedType(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jLLDBTraceGetBinaryData(StringExtractorGDBRemote &packet);
PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
@@ -201,6 +216,10 @@ protected:
PacketResult Handle_g(StringExtractorGDBRemote &packet);
+ PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_QMemTags(StringExtractorGDBRemote &packet);
+
void SetCurrentThreadID(lldb::tid_t tid);
lldb::tid_t GetCurrentThreadID() const;
@@ -219,6 +238,9 @@ protected:
static std::string XMLEncodeAttributeValue(llvm::StringRef value);
+ virtual std::vector<std::string> HandleFeatures(
+ const llvm::ArrayRef<llvm::StringRef> client_features) override;
+
private:
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml();
@@ -244,6 +266,18 @@ private:
void StopSTDIOForwarding();
+ // Read thread-id from packet. If the thread-id is correct, returns it.
+ // Otherwise, returns the error.
+ //
+ // If allow_all is true, then the pid/tid value of -1 ('all') will be allowed.
+ // In any case, the function assumes that exactly one inferior is being
+ // debugged and rejects pid values that do no match that inferior.
+ llvm::Expected<lldb::tid_t> ReadTid(StringExtractorGDBRemote &packet,
+ bool allow_all, lldb::pid_t default_pid);
+
+ // Call SetEnabledExtensions() with appropriate flags on the process.
+ void SetEnabledExtensions(NativeProcessProtocol &process);
+
// For GDBRemoteCommunicationServerLLGS only
GDBRemoteCommunicationServerLLGS(const GDBRemoteCommunicationServerLLGS &) =
delete;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 3462fb7ec8b9..7c2f80dc76b8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -8,7 +8,7 @@
#include "GDBRemoteCommunicationServerPlatform.h"
-#include <errno.h>
+#include <cerrno>
#include <chrono>
#include <csignal>
@@ -153,7 +153,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
}
// Destructor
-GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
+GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() =
+ default;
Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 10006616b0c6..65cf9fb2a834 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -36,7 +36,7 @@ GDBRemoteRegisterContext::GDBRemoteRegisterContext(
: RegisterContext(thread, concrete_frame_idx),
m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),
m_read_all_at_once(read_all_at_once),
- m_write_all_at_once(write_all_at_once) {
+ m_write_all_at_once(write_all_at_once), m_gpacket_cached(false) {
// Resize our vector of bools to contain one bool for every register. We will
// use these boolean values to know when a register value is valid in
// m_reg_data.
@@ -50,13 +50,14 @@ GDBRemoteRegisterContext::GDBRemoteRegisterContext(
}
// Destructor
-GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {}
+GDBRemoteRegisterContext::~GDBRemoteRegisterContext() = default;
void GDBRemoteRegisterContext::InvalidateAllRegisters() {
SetAllRegisterValid(false);
}
void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
+ m_gpacket_cached = b;
std::vector<bool>::iterator pos, end = m_reg_valid.end();
for (pos = m_reg_valid.begin(); pos != end; ++pos)
*pos = b;
@@ -200,7 +201,7 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
if (!GetRegisterIsValid(reg)) {
- if (m_read_all_at_once) {
+ if (m_read_all_at_once && !m_gpacket_cached) {
if (DataBufferSP buffer_sp =
gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
@@ -221,7 +222,10 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
m_reg_valid[i] = false;
}
}
- return true;
+
+ m_gpacket_cached = true;
+ if (GetRegisterIsValid(reg))
+ return true;
} else {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
GDBR_LOG_PACKETS));
@@ -233,9 +237,9 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
" bytes "
"but only got %" PRId64 " bytes.",
m_reg_data.GetByteSize(), buffer_sp->GetByteSize());
+ return false;
}
}
- return false;
}
if (reg_info->value_regs) {
// Process this composite register request by delegating to the
@@ -249,7 +253,8 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
break;
// We have a valid primordial register as our constituent. Grab the
// corresponding register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
+ const RegisterInfo *prim_reg_info =
+ GetRegisterInfo(eRegisterKindProcessPlugin, prim_reg);
if (prim_reg_info == nullptr)
success = false;
else {
@@ -359,7 +364,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
reg_info->byte_size, // dst length
m_reg_data.GetByteOrder())) // dst byte order
{
- GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ GDBRemoteClientBase::Lock lock(gdb_comm);
if (lock) {
if (m_write_all_at_once) {
// Invalidate all register values
@@ -395,7 +400,8 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
break;
// We have a valid primordial register as our constituent. Grab the
// corresponding register info.
- const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
+ const RegisterInfo *value_reg_info =
+ GetRegisterInfo(eRegisterKindProcessPlugin, reg);
if (value_reg_info == nullptr)
success = false;
else
@@ -414,9 +420,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
if (reg_info->invalidate_regs) {
for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
reg != LLDB_INVALID_REGNUM;
- reg = reg_info->invalidate_regs[++idx]) {
- SetRegisterIsValid(reg, false);
- }
+ reg = reg_info->invalidate_regs[++idx])
+ SetRegisterIsValid(ConvertRegisterKindToRegisterNumber(
+ eRegisterKindProcessPlugin, reg),
+ false);
}
return success;
@@ -501,7 +508,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
const bool use_g_packet =
!gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
- GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ GDBRemoteClientBase::Lock lock(gdb_comm);
if (lock) {
if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
InvalidateAllRegisters();
@@ -567,7 +574,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
const bool use_g_packet =
!gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
- GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ GDBRemoteClientBase::Lock lock(gdb_comm);
if (lock) {
// The data_sp contains the G response packet.
if (use_g_packet) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 252d7b359ee8..18fcb73b9815 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -118,6 +118,7 @@ protected:
DataExtractor m_reg_data;
bool m_read_all_at_once;
bool m_write_all_at_once;
+ bool m_gpacket_cached;
private:
// Helper function for ReadRegisterBytes().
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 1214812b60b0..b8a737586eb4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -8,8 +8,8 @@
#include "lldb/Host/Config.h"
-#include <errno.h>
-#include <stdlib.h>
+#include <cerrno>
+#include <cstdlib>
#if LLDB_ENABLE_POSIX
#include <netinet/in.h>
#include <sys/mman.h>
@@ -20,8 +20,8 @@
#if defined(__APPLE__)
#include <sys/sysctl.h>
#endif
+#include <ctime>
#include <sys/types.h>
-#include <time.h>
#include <algorithm>
#include <csignal>
@@ -137,7 +137,7 @@ public:
m_collection_sp->Initialize(g_processgdbremote_properties);
}
- ~PluginProperties() override {}
+ ~PluginProperties() override = default;
uint64_t GetPacketTimeout() {
const uint32_t idx = ePropertyPacketTimeout;
@@ -215,6 +215,10 @@ ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
return process_sp;
}
+std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() {
+ return std::chrono::seconds(GetGlobalPluginProperties()->GetPacketTimeout());
+}
+
bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) {
if (plugin_specified_by_name)
@@ -463,7 +467,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
assert(packet_len < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
GDBRemoteCommunication::PacketResult::Success) {
response_type = response.GetResponseType();
if (response_type == StringExtractorGDBRemote::eResponse) {
@@ -1013,7 +1017,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
for (size_t idx = 0; idx < num_cmds; idx++) {
StringExtractorGDBRemote response;
m_gdb_comm.SendPacketAndWaitForResponse(
- GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
+ GetExtraStartupCommands().GetArgumentAtIndex(idx), response);
}
return error;
}
@@ -1040,6 +1044,12 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
process_arch.GetTriple().getTriple());
}
+ if (int addresssable_bits = m_gdb_comm.GetAddressingBits()) {
+ lldb::addr_t address_mask = ~((1ULL << addresssable_bits) - 1);
+ SetCodeAddressMask(address_mask);
+ SetDataAddressMask(address_mask);
+ }
+
if (process_arch.IsValid()) {
const ArchSpec &target_arch = GetTarget().GetArchitecture();
if (target_arch.IsValid()) {
@@ -1201,34 +1211,26 @@ Status ProcessGDBRemote::DoAttachToProcessWithName(
return error;
}
-lldb::user_id_t ProcessGDBRemote::StartTrace(const TraceOptions &options,
- Status &error) {
- return m_gdb_comm.SendStartTracePacket(options, error);
-}
-
-Status ProcessGDBRemote::StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) {
- return m_gdb_comm.SendStopTracePacket(uid, thread_id);
+llvm::Expected<TraceSupportedResponse> ProcessGDBRemote::TraceSupported() {
+ return m_gdb_comm.SendTraceSupported(GetInterruptTimeout());
}
-Status ProcessGDBRemote::GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- return m_gdb_comm.SendGetDataPacket(uid, thread_id, buffer, offset);
+llvm::Error ProcessGDBRemote::TraceStop(const TraceStopRequest &request) {
+ return m_gdb_comm.SendTraceStop(request, GetInterruptTimeout());
}
-Status ProcessGDBRemote::GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- return m_gdb_comm.SendGetMetaDataPacket(uid, thread_id, buffer, offset);
+llvm::Error ProcessGDBRemote::TraceStart(const llvm::json::Value &request) {
+ return m_gdb_comm.SendTraceStart(request, GetInterruptTimeout());
}
-Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid,
- TraceOptions &options) {
- return m_gdb_comm.SendGetTraceConfigPacket(uid, options);
+llvm::Expected<std::string>
+ProcessGDBRemote::TraceGetState(llvm::StringRef type) {
+ return m_gdb_comm.SendTraceGetState(type, GetInterruptTimeout());
}
-llvm::Expected<TraceTypeInfo> ProcessGDBRemote::GetSupportedTraceType() {
- return m_gdb_comm.SendGetSupportedTraceType();
+llvm::Expected<std::vector<uint8_t>>
+ProcessGDBRemote::TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {
+ return m_gdb_comm.SendTraceGetBinaryData(request, GetInterruptTimeout());
}
void ProcessGDBRemote::DidExit() {
@@ -1473,7 +1475,7 @@ void ProcessGDBRemote::HandleStopReplySequence() {
while (true) {
// Send vStopped
StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+ m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response);
// OK represents end of signal list
if (response.IsOKResponse())
@@ -1493,22 +1495,22 @@ void ProcessGDBRemote::ClearThreadIDList() {
m_thread_pcs.clear();
}
-size_t
-ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) {
+size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(
+ llvm::StringRef value) {
m_thread_ids.clear();
- size_t comma_pos;
- lldb::tid_t tid;
- while ((comma_pos = value.find(',')) != std::string::npos) {
- value[comma_pos] = '\0';
- // thread in big endian hex
- tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back(tid);
- value.erase(0, comma_pos + 1);
- }
- tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back(tid);
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ StringExtractorGDBRemote thread_ids{value};
+
+ do {
+ auto pid_tid = thread_ids.GetPidTid(pid);
+ if (pid_tid && pid_tid->first == pid) {
+ lldb::tid_t tid = pid_tid->second;
+ if (tid != LLDB_INVALID_THREAD_ID &&
+ tid != StringExtractorGDBRemote::AllProcesses)
+ m_thread_ids.push_back(tid);
+ }
+ } while (thread_ids.GetChar() == ',');
+
return m_thread_ids.size();
}
@@ -1525,7 +1527,7 @@ ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(std::string &value) {
value.erase(0, comma_pos + 1);
}
pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_THREAD_ID)
+ if (pc != LLDB_INVALID_ADDRESS)
m_thread_pcs.push_back(pc);
return m_thread_pcs.size();
}
@@ -1750,7 +1752,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (thread_sp) {
ThreadGDBRemote *gdb_thread =
static_cast<ThreadGDBRemote *>(thread_sp.get());
- gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+ RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext());
+
+ gdb_reg_ctx_sp->InvalidateIfNeeded(true);
auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid);
if (iter != m_thread_ids.end()) {
@@ -1762,7 +1766,10 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
DataBufferSP buffer_sp(new DataBufferHeap(
reg_value_extractor.GetStringRef().size() / 2, 0));
reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
- gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
+ uint32_t lldb_regnum =
+ gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindProcessPlugin, pair.first);
+ gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData());
}
// AArch64 SVE specific code below calls AArch64SVEReconfigure to update
@@ -1827,8 +1834,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// If the current pc is a breakpoint site then the StopInfo
// should be set to Breakpoint Otherwise, it will be set to
// Trace.
- if (bp_site_sp &&
- bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithBreakpointSiteID(
*thread_sp, bp_site_sp->GetID()));
@@ -1848,7 +1854,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// breakpoint here, that will be taken care of when the thread
// resumes and notices that there's a breakpoint under the pc.
handled = true;
- if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp->ValidForThisThread(*thread_sp)) {
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithBreakpointSiteID(
*thread_sp, bp_site_sp->GetID()));
@@ -1899,6 +1905,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithExec(*thread_sp));
handled = true;
+ } else if (reason == "processor trace") {
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonProcessorTrace(
+ *thread_sp, description.c_str()));
}
} else if (!signo) {
addr_t pc = thread_sp->GetRegisterContext()->GetPC();
@@ -1911,7 +1920,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// as such. This can happen when the thread is involuntarily
// interrupted (e.g. due to stops on other threads) just as it is
// about to execute the breakpoint instruction.
- if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithBreakpointSiteID(
*thread_sp, bp_site_sp->GetID()));
@@ -1936,7 +1945,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// reason. We don't need to worry about stepping over the
// breakpoint here, that will be taken care of when the thread
// resumes and notices that there's a breakpoint under the pc.
- if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (bp_site_sp->ValidForThisThread(*thread_sp)) {
if (m_breakpoint_pc_offset != 0)
thread_sp->GetRegisterContext()->SetPC(pc);
thread_sp->SetStopInfo(
@@ -2139,6 +2148,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
}
StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
stop_packet.SetFilePos(0);
const char stop_type = stop_packet.GetChar();
switch (stop_type) {
@@ -2153,14 +2163,12 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
if (stop_id == 0) {
// Our first stop, make sure we have a process ID, and also make sure we
// know about our registers
- if (GetID() == LLDB_INVALID_PROCESS_ID) {
- lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
- SetID(pid);
- }
+ if (GetID() == LLDB_INVALID_PROCESS_ID && pid != LLDB_INVALID_PROCESS_ID)
+ SetID(pid);
BuildDynamicRegisterInfo(true);
}
// Stop with signal and thread info
+ lldb::pid_t stop_pid = LLDB_INVALID_PROCESS_ID;
lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
const uint8_t signo = stop_packet.GetHexU8();
llvm::StringRef key;
@@ -2189,24 +2197,18 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
value.getAsInteger(16, x);
exc_data.push_back(x);
} else if (key.compare("thread") == 0) {
- // thread in big endian hex
- if (value.getAsInteger(16, tid))
+ // thread-id
+ StringExtractorGDBRemote thread_id{value};
+ auto pid_tid = thread_id.GetPidTid(pid);
+ if (pid_tid) {
+ stop_pid = pid_tid->first;
+ tid = pid_tid->second;
+ } else
tid = LLDB_INVALID_THREAD_ID;
} else if (key.compare("threads") == 0) {
std::lock_guard<std::recursive_mutex> guard(
m_thread_list_real.GetMutex());
-
- m_thread_ids.clear();
- // A comma separated list of all threads in the current
- // process that includes the thread for this stop reply packet
- lldb::tid_t tid;
- while (!value.empty()) {
- llvm::StringRef tid_str;
- std::tie(tid_str, value) = value.split(',');
- if (tid_str.getAsInteger(16, tid))
- tid = LLDB_INVALID_THREAD_ID;
- m_thread_ids.push_back(tid);
- }
+ UpdateThreadIDsFromStopReplyThreadsValue(value);
} else if (key.compare("thread-pcs") == 0) {
m_thread_pcs.clear();
// A comma separated list of all threads in the current
@@ -2319,6 +2321,14 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
}
}
+ if (stop_pid != LLDB_INVALID_PROCESS_ID && stop_pid != pid) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ LLDB_LOG(log,
+ "Received stop for incorrect PID = {0} (inferior PID = {1})",
+ stop_pid, pid);
+ return eStateInvalid;
+ }
+
if (tid == LLDB_INVALID_THREAD_ID) {
// A thread id may be invalid if the response is old style 'S' packet
// which does not provide the
@@ -2406,7 +2416,7 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) {
// file handle and debugserver will go away, and we can be done...
m_gdb_comm.Disconnect();
} else
- caused_stop = m_gdb_comm.Interrupt();
+ caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout());
return error;
}
@@ -2557,11 +2567,11 @@ Status ProcessGDBRemote::DoDestroy() {
if (m_gdb_comm.IsConnected()) {
if (m_public_state.GetValue() != eStateAttaching) {
StringExtractorGDBRemote response;
- bool send_async = true;
GDBRemoteCommunication::ScopedTimeout(m_gdb_comm,
std::chrono::seconds(3));
- if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, send_async) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse("k", response,
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
char packet_cmd = response.GetChar(0);
@@ -2725,7 +2735,8 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
assert(packet_len + 1 < (int)sizeof(packet));
UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, true) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsNormalResponse()) {
error.Clear();
@@ -2761,6 +2772,37 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
return 0;
}
+bool ProcessGDBRemote::SupportsMemoryTagging() {
+ return m_gdb_comm.GetMemoryTaggingSupported();
+}
+
+llvm::Expected<std::vector<uint8_t>>
+ProcessGDBRemote::DoReadMemoryTags(lldb::addr_t addr, size_t len,
+ int32_t type) {
+ // By this point ReadMemoryTags has validated that tagging is enabled
+ // for this target/process/address.
+ DataBufferSP buffer_sp = m_gdb_comm.ReadMemoryTags(addr, len, type);
+ if (!buffer_sp) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error reading memory tags from remote");
+ }
+
+ // Return the raw tag data
+ llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
+ std::vector<uint8_t> got;
+ got.reserve(tag_data.size());
+ std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
+ return got;
+}
+
+Status ProcessGDBRemote::DoWriteMemoryTags(lldb::addr_t addr, size_t len,
+ int32_t type,
+ const std::vector<uint8_t> &tags) {
+ // By now WriteMemoryTags should have validated that tagging is enabled
+ // for this target/process.
+ return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
+}
+
Status ProcessGDBRemote::WriteObjectFile(
std::vector<ObjectFile::LoadableData> entries) {
Status error;
@@ -2851,7 +2893,7 @@ Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) {
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- true) ==
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsOKResponse()) {
m_erased_flash_ranges.Insert(range, true);
@@ -2880,7 +2922,8 @@ Status ProcessGDBRemote::FlashDone() {
if (m_erased_flash_ranges.IsEmpty())
return status;
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response, true) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response,
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsOKResponse()) {
m_erased_flash_ranges.Clear();
@@ -2941,7 +2984,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
}
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- true) ==
+ GetInterruptTimeout()) ==
GDBRemoteCommunication::PacketResult::Success) {
if (response.IsOKResponse()) {
error.Clear();
@@ -3117,7 +3160,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
(!bp_site->HardwareRequired())) {
// Try to send off a software breakpoint packet ($Z0)
uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
- eBreakpointSoftware, true, addr, bp_op_size);
+ eBreakpointSoftware, true, addr, bp_op_size, GetInterruptTimeout());
if (error_no == 0) {
// The breakpoint was placed successfully
bp_site->SetEnabled(true);
@@ -3157,7 +3200,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
// Try to send off a hardware breakpoint packet ($Z1)
uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
- eBreakpointHardware, true, addr, bp_op_size);
+ eBreakpointHardware, true, addr, bp_op_size, GetInterruptTimeout());
if (error_no == 0) {
// The breakpoint was placed successfully
bp_site->SetEnabled(true);
@@ -3221,13 +3264,15 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
case BreakpointSite::eHardware:
if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false,
- addr, bp_op_size))
+ addr, bp_op_size,
+ GetInterruptTimeout()))
error.SetErrorToGenericError();
break;
case BreakpointSite::eExternal: {
if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false,
- addr, bp_op_size))
+ addr, bp_op_size,
+ GetInterruptTimeout()))
error.SetErrorToGenericError();
} break;
}
@@ -3283,7 +3328,8 @@ Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
// Pass down an appropriate z/Z packet...
if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
- wp->GetByteSize()) == 0) {
+ wp->GetByteSize(),
+ GetInterruptTimeout()) == 0) {
wp->SetEnabled(true, notify);
return error;
} else
@@ -3329,7 +3375,8 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
GDBStoppointType type = GetGDBStoppointType(wp);
// Pass down an appropriate z/Z packet...
if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
- wp->GetByteSize()) == 0) {
+ wp->GetByteSize(),
+ GetInterruptTimeout()) == 0) {
wp->SetEnabled(false, notify);
return error;
} else
@@ -3354,7 +3401,7 @@ Status ProcessGDBRemote::DoSignal(int signo) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo);
- if (!m_gdb_comm.SendAsyncSignal(signo))
+ if (!m_gdb_comm.SendAsyncSignal(signo, GetInterruptTimeout()))
error.SetErrorStringWithFormat("failed to send signal %i", signo);
return error;
}
@@ -3682,12 +3729,25 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
__FUNCTION__, arg, process->GetID());
EventSP event_sp;
+
+ // We need to ignore any packets that come in after we have
+ // have decided the process has exited. There are some
+ // situations, for instance when we try to interrupt a running
+ // process and the interrupt fails, where another packet might
+ // get delivered after we've decided to give up on the process.
+ // But once we've decided we are done with the process we will
+ // not be in a state to do anything useful with new packets.
+ // So it is safer to simply ignore any remaining packets by
+ // explicitly checking for eStateExited before reentering the
+ // fetch loop.
+
bool done = false;
- while (!done) {
+ while (!done && process->GetPrivateState() != eStateExited) {
LLDB_LOGF(log,
"ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
") listener.WaitForEvent (NULL, event_sp)...",
__FUNCTION__, arg, process->GetID());
+
if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
@@ -3719,7 +3779,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// send the vCont packet
if (!process->GetGDBRemote().SendvContPacket(
llvm::StringRef(continue_cstr, continue_cstr_len),
- response)) {
+ process->GetInterruptTimeout(), response)) {
// Something went wrong
done = true;
break;
@@ -3731,6 +3791,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
*process, *process->GetUnixSignals(),
llvm::StringRef(continue_cstr, continue_cstr_len),
+ process->GetInterruptTimeout(),
response);
// We need to immediately clear the thread ID list so we are sure
@@ -3786,6 +3847,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
} else {
process->SetExitStatus(-1, "lost connection");
}
+ done = true;
break;
}
@@ -4024,8 +4086,7 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {
StringExtractorGDBRemote response;
response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
GDBRemoteCommunication::PacketResult::Success) {
StringExtractorGDBRemote::ResponseType response_type =
response.GetResponseType();
@@ -4097,8 +4158,7 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
StringExtractorGDBRemote response;
response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
GDBRemoteCommunication::PacketResult::Success) {
StringExtractorGDBRemote::ResponseType response_type =
response.GetResponseType();
@@ -4131,8 +4191,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
StringExtractorGDBRemote response;
response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) ==
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
GDBRemoteCommunication::PacketResult::Success) {
StringExtractorGDBRemote::ResponseType response_type =
response.GetResponseType();
@@ -4898,8 +4957,7 @@ Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
packet.PutStringAsRawHex8(file_path);
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
- false) !=
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
GDBRemoteCommunication::PacketResult::Success)
return Status("Sending qFileLoadAddress packet failed");
@@ -5135,7 +5193,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectProcessGDBRemoteSpeedTest() override {}
+ ~CommandObjectProcessGDBRemoteSpeedTest() override = default;
Options *GetOptions() override { return &m_option_group; }
@@ -5186,7 +5244,7 @@ public:
: CommandObjectParsed(interpreter, "process plugin packet history",
"Dumps the packet history buffer. ", nullptr) {}
- ~CommandObjectProcessGDBRemotePacketHistory() override {}
+ ~CommandObjectProcessGDBRemotePacketHistory() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5217,7 +5275,7 @@ public:
"Maximum size that lldb will try to read/write one one chunk.",
nullptr) {}
- ~CommandObjectProcessGDBRemotePacketXferSize() override {}
+ ~CommandObjectProcessGDBRemotePacketXferSize() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5226,7 +5284,6 @@ public:
"amount to be transferred when "
"reading/writing",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -5259,7 +5316,7 @@ public:
"stripped from the result.",
nullptr) {}
- ~CommandObjectProcessGDBRemotePacketSend() override {}
+ ~CommandObjectProcessGDBRemotePacketSend() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5267,7 +5324,6 @@ public:
result.AppendErrorWithFormat(
"'%s' takes a one or more packet content arguments",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -5276,10 +5332,9 @@ public:
if (process) {
for (size_t i = 0; i < argc; ++i) {
const char *packet_cstr = command.GetArgumentAtIndex(0);
- bool send_async = true;
StringExtractorGDBRemote response;
process->GetGDBRemote().SendPacketAndWaitForResponse(
- packet_cstr, response, send_async);
+ packet_cstr, response, process->GetInterruptTimeout());
result.SetStatus(eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
output_strm.Printf(" packet: %s\n", packet_cstr);
@@ -5310,14 +5365,13 @@ public:
"encoded into a valid 'qRcmd' packet, sent and the "
"response will be printed.") {}
- ~CommandObjectProcessGDBRemotePacketMonitor() override {}
+ ~CommandObjectProcessGDBRemotePacketMonitor() override = default;
bool DoExecute(llvm::StringRef command,
CommandReturnObject &result) override {
if (command.empty()) {
result.AppendErrorWithFormat("'%s' takes a command string argument",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -5328,11 +5382,10 @@ public:
packet.PutCString("qRcmd,");
packet.PutBytesAsRawHex8(command.data(), command.size());
- bool send_async = true;
StringExtractorGDBRemote response;
Stream &output_strm = result.GetOutputStream();
process->GetGDBRemote().SendPacketAndReceiveResponseWithOutputSupport(
- packet.GetString(), response, send_async,
+ packet.GetString(), response, process->GetInterruptTimeout(),
[&output_strm](llvm::StringRef output) { output_strm << output; });
result.SetStatus(eReturnStatusSuccessFinishResult);
output_strm.Printf(" packet: %s\n", packet.GetData());
@@ -5374,7 +5427,7 @@ public:
interpreter)));
}
- ~CommandObjectProcessGDBRemotePacket() override {}
+ ~CommandObjectProcessGDBRemotePacket() override = default;
};
class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {
@@ -5389,7 +5442,7 @@ public:
CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));
}
- ~CommandObjectMultiwordProcessGDBRemote() override {}
+ ~CommandObjectMultiwordProcessGDBRemote() override = default;
};
CommandObject *ProcessGDBRemote::GetPluginCommandObject() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 0921bf17c4e4..fe04cdddd0f5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -68,6 +68,8 @@ public:
static const char *GetPluginDescriptionStatic();
+ static std::chrono::seconds GetPacketTimeout();
+
// Check if a given Process
bool CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) override;
@@ -163,22 +165,16 @@ public:
Status GetWatchpointSupportInfo(uint32_t &num) override;
- lldb::user_id_t StartTrace(const TraceOptions &options,
- Status &error) override;
-
- Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) override;
+ llvm::Expected<TraceSupportedResponse> TraceSupported() override;
- Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) override;
+ llvm::Error TraceStop(const TraceStopRequest &request) override;
- Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) override;
+ llvm::Error TraceStart(const llvm::json::Value &request) override;
- llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override;
+ llvm::Expected<std::string> TraceGetState(llvm::StringRef type) override;
- Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) override;
+ llvm::Expected<std::vector<uint8_t>>
+ TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override;
Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
@@ -239,6 +235,8 @@ protected:
friend class GDBRemoteCommunicationClient;
friend class GDBRemoteRegisterContext;
+ bool SupportsMemoryTagging() override;
+
/// Broadcaster event bits definitions.
enum {
eBroadcastBitAsyncContinue = (1 << 0),
@@ -339,7 +337,7 @@ protected:
size_t UpdateThreadPCsFromStopReplyThreadsValue(std::string &value);
- size_t UpdateThreadIDsFromStopReplyThreadsValue(std::string &value);
+ size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value);
bool HandleNotifyPacket(StringExtractorGDBRemote &packet);
@@ -410,6 +408,12 @@ protected:
bool HasErased(FlashRange range);
+ llvm::Expected<std::vector<uint8_t>>
+ DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override;
+
+ Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
+ const std::vector<uint8_t> &tags) override;
+
private:
// For ProcessGDBRemote only
std::string m_partial_profile_data;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 05a48acc2f7a..385557422758 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -138,10 +138,10 @@ private:
///
/// \param[in] module_sp The module to grab the .text section from.
///
-/// \param[in/out] breakpad_uuid A vector that will receive the calculated
+/// \param[in,out] breakpad_uuid A vector that will receive the calculated
/// breakpad .text hash.
///
-/// \param[in/out] facebook_uuid A vector that will receive the calculated
+/// \param[in,out] facebook_uuid A vector that will receive the calculated
/// facebook .text hash.
///
void HashElfTextSection(ModuleSP module_sp, std::vector<uint8_t> &breakpad_uuid,
@@ -548,7 +548,7 @@ void ProcessMinidump::ReadModuleList() {
// check if the process is wow64 - a 32 bit windows process running on a
// 64 bit windows
- if (llvm::StringRef(name).endswith_lower("wow64.dll")) {
+ if (llvm::StringRef(name).endswith_insensitive("wow64.dll")) {
m_is_wow64 = true;
}
@@ -871,7 +871,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectProcessMinidumpDump() override {}
+ ~CommandObjectProcessMinidumpDump() override = default;
Options *GetOptions() override { return &m_option_group; }
@@ -880,7 +880,6 @@ public:
if (argc > 0) {
result.AppendErrorWithFormat("'%s' take no arguments, only options",
m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
return false;
}
SetDefaultOptionsIfNoneAreSet();
@@ -1001,7 +1000,7 @@ public:
CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
}
- ~CommandObjectMultiwordProcessMinidump() override {}
+ ~CommandObjectMultiwordProcessMinidump() override = default;
};
CommandObject *ProcessMinidump::GetPluginCommandObject() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
index eb48785263fc..7e309e8322a8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
@@ -16,7 +16,7 @@
#include "lldb/lldb-enumerations.h"
// C includes
-#include <assert.h>
+#include <cassert>
// C++ includes
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
index c7809c5f19b6..e2b7c0e362a7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
@@ -14,7 +14,7 @@
#include "lldb/lldb-enumerations.h"
// C includes
-#include <assert.h>
+#include <cassert>
// C++ includes
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
index e146a1a1af92..1fbc52815238 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -38,7 +38,7 @@ ThreadMinidump::ThreadMinidump(Process &process, const minidump::Thread &td,
: Thread(process, td.ThreadId), m_thread_reg_ctx_sp(),
m_gpregset_data(gpregset_data) {}
-ThreadMinidump::~ThreadMinidump() {}
+ThreadMinidump::~ThreadMinidump() = default;
void ThreadMinidump::RefreshStateAfterStop() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
new file mode 100644
index 000000000000..09e9375b6f66
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -0,0 +1,313 @@
+//===-- ScriptedProcess.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ScriptedProcess.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupBoolean.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/RegisterContext.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "lldb/Utility/State.h"
+
+#include <mutex>
+
+LLDB_PLUGIN_DEFINE(ScriptedProcess)
+
+using namespace lldb;
+using namespace lldb_private;
+
+ConstString ScriptedProcess::GetPluginNameStatic() {
+ static ConstString g_name("ScriptedProcess");
+ return g_name;
+}
+
+const char *ScriptedProcess::GetPluginDescriptionStatic() {
+ return "Scripted Process plug-in.";
+}
+
+static constexpr lldb::ScriptLanguage g_supported_script_languages[] = {
+ ScriptLanguage::eScriptLanguagePython,
+};
+
+bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) {
+ llvm::ArrayRef<lldb::ScriptLanguage> supported_languages =
+ llvm::makeArrayRef(g_supported_script_languages);
+
+ return llvm::is_contained(supported_languages, language);
+}
+
+void ScriptedProcess::CheckInterpreterAndScriptObject() const {
+ lldbassert(m_interpreter && "Invalid Script Interpreter.");
+ lldbassert(m_script_object_sp && "Invalid Script Object.");
+}
+
+lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *file,
+ bool can_connect) {
+ if (!target_sp ||
+ !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage()))
+ return nullptr;
+
+ Status error;
+ ScriptedProcess::ScriptedProcessInfo scripted_process_info(
+ target_sp->GetProcessLaunchInfo());
+
+ auto process_sp = std::make_shared<ScriptedProcess>(
+ target_sp, listener_sp, scripted_process_info, error);
+
+ if (error.Fail() || !process_sp || !process_sp->m_script_object_sp ||
+ !process_sp->m_script_object_sp->IsValid()) {
+ LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "%s",
+ error.AsCString());
+ return nullptr;
+ }
+
+ return process_sp;
+}
+
+bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ return true;
+}
+
+ScriptedProcess::ScriptedProcess(
+ lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const ScriptedProcess::ScriptedProcessInfo &scripted_process_info,
+ Status &error)
+ : Process(target_sp, listener_sp),
+ m_scripted_process_info(scripted_process_info) {
+
+ if (!target_sp) {
+ error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
+ __FUNCTION__, "Invalid target");
+ return;
+ }
+
+ m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
+
+ if (!m_interpreter) {
+ error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
+ __FUNCTION__,
+ "Debugger has no Script Interpreter");
+ return;
+ }
+
+ StructuredData::ObjectSP object_sp = GetInterface().CreatePluginObject(
+ m_scripted_process_info.GetClassName().c_str(), target_sp,
+ m_scripted_process_info.GetDictionarySP());
+
+ if (!object_sp || !object_sp->IsValid()) {
+ error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
+ __FUNCTION__,
+ "Failed to create valid script object");
+ return;
+ }
+
+ m_script_object_sp = object_sp;
+}
+
+ScriptedProcess::~ScriptedProcess() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves to
+ // make sure all of the broadcaster cleanup goes as planned. If we destruct
+ // this class, then Process::~Process() might have problems trying to fully
+ // destroy the broadcaster.
+ Finalize();
+}
+
+void ScriptedProcess::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
+}
+
+void ScriptedProcess::Terminate() {
+ PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance);
+}
+
+ConstString ScriptedProcess::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ScriptedProcess::GetPluginVersion() { return 1; }
+
+Status ScriptedProcess::DoLoadCore() {
+ ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo();
+
+ return DoLaunch(nullptr, launch_info);
+}
+
+Status ScriptedProcess::DoLaunch(Module *exe_module,
+ ProcessLaunchInfo &launch_info) {
+ CheckInterpreterAndScriptObject();
+
+ /* FIXME: This doesn't reflect how lldb actually launches a process.
+ In reality, it attaches to debugserver, then resume the process. */
+ Status error = GetInterface().Launch();
+ SetPrivateState(eStateRunning);
+
+ if (error.Fail())
+ return error;
+
+ // TODO: Fetch next state from stopped event queue then send stop event
+ // const StateType state = SetThreadStopInfo(response);
+ // if (state != eStateInvalid) {
+ // SetPrivateState(state);
+
+ SetPrivateState(eStateStopped);
+
+ UpdateThreadListIfNeeded();
+ GetThreadList();
+
+ return {};
+}
+
+void ScriptedProcess::DidLaunch() {
+ CheckInterpreterAndScriptObject();
+ m_pid = GetInterface().GetProcessID();
+}
+
+Status ScriptedProcess::DoResume() {
+ CheckInterpreterAndScriptObject();
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ // FIXME: Fetch data from thread.
+ const StateType thread_resume_state = eStateRunning;
+ LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__,
+ StateAsCString(thread_resume_state));
+
+ bool resume = (thread_resume_state == eStateRunning);
+ assert(thread_resume_state == eStateRunning && "invalid thread resume state");
+
+ Status error;
+ if (resume) {
+ LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__);
+
+ SetPrivateState(eStateRunning);
+ SetPrivateState(eStateStopped);
+ error = GetInterface().Resume();
+ }
+
+ return error;
+}
+
+Status ScriptedProcess::DoStop() {
+ CheckInterpreterAndScriptObject();
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (GetInterface().ShouldStop()) {
+ SetPrivateState(eStateStopped);
+ LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__);
+ return {};
+ }
+
+ LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__);
+ return GetInterface().Stop();
+}
+
+Status ScriptedProcess::DoDestroy() { return Status(); }
+
+bool ScriptedProcess::IsAlive() {
+ if (m_interpreter && m_script_object_sp)
+ return GetInterface().IsAlive();
+ return false;
+}
+
+size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Status &error) {
+
+ auto error_with_message = [&error](llvm::StringRef message) {
+ error.SetErrorString(message);
+ return 0;
+ };
+
+ if (!m_interpreter)
+ return error_with_message("No interpreter.");
+
+ lldb::DataExtractorSP data_extractor_sp =
+ GetInterface().ReadMemoryAtAddress(addr, size, error);
+
+ if (!data_extractor_sp || error.Fail())
+ return 0;
+
+ offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
+ 0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder());
+
+ if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET)
+ return error_with_message("Failed to copy read memory to buffer.");
+
+ return size;
+}
+
+ArchSpec ScriptedProcess::GetArchitecture() {
+ return GetTarget().GetArchitecture();
+}
+
+Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region) {
+ // TODO: Implement
+ return Status();
+}
+
+Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos &region_list) {
+ CheckInterpreterAndScriptObject();
+
+ lldb::addr_t address = 0;
+ lldb::MemoryRegionInfoSP mem_region_sp = nullptr;
+
+ while ((mem_region_sp =
+ GetInterface().GetMemoryRegionContainingAddress(address))) {
+ auto range = mem_region_sp->GetRange();
+ address += range.GetRangeBase() + range.GetByteSize();
+ region_list.push_back(*mem_region_sp.get());
+ }
+
+ return {};
+}
+
+void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); }
+
+bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // TODO: Implement
+ // This is supposed to get the current set of threads, if any of them are in
+ // old_thread_list then they get copied to new_thread_list, and then any
+ // actually new threads will get added to new_thread_list.
+ return new_thread_list.GetSize(false) > 0;
+}
+
+bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
+ info.Clear();
+ info.SetProcessID(GetID());
+ info.SetArchitecture(GetArchitecture());
+ lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+ if (module_sp) {
+ const bool add_exe_file_as_first_arg = false;
+ info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
+ add_exe_file_as_first_arg);
+ }
+ return true;
+}
+
+ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
+ return m_interpreter->GetScriptedProcessInterface();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
new file mode 100644
index 000000000000..98c1a1ca4fe9
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -0,0 +1,119 @@
+//===-- ScriptedProcess.h ------------------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
+#define LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
+
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Status.h"
+
+#include <mutex>
+
+namespace lldb_private {
+
+class ScriptedProcess : public Process {
+protected:
+ class ScriptedProcessInfo {
+ public:
+ ScriptedProcessInfo(const ProcessLaunchInfo &launch_info) {
+ m_class_name = launch_info.GetScriptedProcessClassName();
+ m_dictionary_sp = launch_info.GetScriptedProcessDictionarySP();
+ }
+
+ std::string GetClassName() const { return m_class_name; }
+ StructuredData::DictionarySP GetDictionarySP() const {
+ return m_dictionary_sp;
+ }
+
+ private:
+ std::string m_class_name;
+ StructuredData::DictionarySP m_dictionary_sp;
+ };
+
+public:
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path,
+ bool can_connect);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const ScriptedProcess::ScriptedProcessInfo &launch_info,
+ Status &error);
+
+ ~ScriptedProcess() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ DynamicLoader *GetDynamicLoader() override { return nullptr; }
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ SystemRuntime *GetSystemRuntime() override { return nullptr; }
+
+ Status DoLoadCore() override;
+
+ Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
+
+ void DidLaunch() override;
+
+ Status DoResume() override;
+
+ Status DoDestroy() override;
+
+ void RefreshStateAfterStop() override{};
+
+ bool IsAlive() override;
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Status &error) override;
+
+ ArchSpec GetArchitecture();
+
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
+ Status
+ GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) override;
+
+ bool GetProcessInfo(ProcessInstanceInfo &info) override;
+
+protected:
+ Status DoStop();
+
+ void Clear();
+
+ bool DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
+
+private:
+ void CheckInterpreterAndScriptObject() const;
+ ScriptedProcessInterface &GetInterface() const;
+ static bool IsScriptLanguageSupported(lldb::ScriptLanguage language);
+
+ // Member variables.
+ const ScriptedProcessInfo m_scripted_process_info;
+ lldb_private::ScriptInterpreter *m_interpreter = nullptr;
+ lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr;
+ //@}
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
index f14e2732f6eb..e99b7b88379a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -30,6 +30,9 @@ extern "C" llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction(
lua_State *L, lldb::StackFrameSP stop_frame_sp,
lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl);
+extern "C" llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction(
+ lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp);
+
#if _MSC_VER
#pragma warning (pop)
#endif
@@ -113,6 +116,32 @@ Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
bp_loc_sp, extra_args_impl);
}
+llvm::Error Lua::RegisterWatchpointCallback(void *baton, const char *body) {
+ lua_pushlightuserdata(m_lua_state, baton);
+ const char *fmt_str = "return function(frame, wp, ...) {0} end";
+ std::string func_str = llvm::formatv(fmt_str, body).str();
+ if (luaL_dostring(m_lua_state, func_str.c_str()) != LUA_OK) {
+ llvm::Error e = llvm::make_error<llvm::StringError>(
+ llvm::formatv("{0}", lua_tostring(m_lua_state, -1)),
+ llvm::inconvertibleErrorCode());
+ // Pop error message from the stack.
+ lua_pop(m_lua_state, 2);
+ return e;
+ }
+ lua_settable(m_lua_state, LUA_REGISTRYINDEX);
+ return llvm::Error::success();
+}
+
+llvm::Expected<bool>
+Lua::CallWatchpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
+ lldb::WatchpointSP wp_sp) {
+
+ lua_pushlightuserdata(m_lua_state, baton);
+ lua_gettable(m_lua_state, LUA_REGISTRYINDEX);
+ return LLDBSwigLuaWatchpointCallbackFunction(m_lua_state, stop_frame_sp,
+ wp_sp);
+}
+
llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) {
int error =
luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer");
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
index 873440f0aab3..5daedf835b9b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
@@ -37,6 +37,10 @@ public:
CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
lldb::BreakpointLocationSP bp_loc_sp,
StructuredData::ObjectSP extra_args_sp);
+ llvm::Error RegisterWatchpointCallback(void *baton, const char *body);
+ llvm::Expected<bool> CallWatchpointCallback(void *baton,
+ lldb::StackFrameSP stop_frame_sp,
+ lldb::WatchpointSP wp_sp);
llvm::Error LoadModule(llvm::StringRef filename);
llvm::Error CheckSyntax(llvm::StringRef buffer);
llvm::Error ChangeIO(FILE *out, FILE *err);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
index 920e334f51aa..ef46401c8b46 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -58,7 +58,13 @@ public:
const char *instructions = nullptr;
switch (m_active_io_handler) {
case eIOHandlerNone:
+ break;
case eIOHandlerWatchpoint:
+ instructions = "Enter your Lua command(s). Type 'quit' to end.\n"
+ "The commands are compiled as the body of the following "
+ "Lua function\n"
+ "function (frame, wp) end\n";
+ SetPrompt(llvm::StringRef("..> "));
break;
case eIOHandlerBreakpoint:
instructions = "Enter your Lua command(s). Type 'quit' to end.\n"
@@ -78,7 +84,8 @@ public:
StringList &lines) override {
size_t last = lines.GetSize() - 1;
if (IsQuitCommand(lines.GetStringAtIndex(last))) {
- if (m_active_io_handler == eIOHandlerBreakpoint)
+ if (m_active_io_handler == eIOHandlerBreakpoint ||
+ m_active_io_handler == eIOHandlerWatchpoint)
lines.DeleteStringAtIndex(last);
return true;
}
@@ -90,17 +97,19 @@ public:
// Lua always errors out to incomplete code with '<eof>'
return error_str.find("<eof>") == std::string::npos;
}
- // The breakpoint handler only exits with a explicit 'quit'
- return m_active_io_handler != eIOHandlerBreakpoint;
+ // The breakpoint and watchpoint handler only exits with a explicit 'quit'
+ return m_active_io_handler != eIOHandlerBreakpoint &&
+ m_active_io_handler != eIOHandlerWatchpoint;
}
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &data) override {
switch (m_active_io_handler) {
case eIOHandlerBreakpoint: {
- auto *bp_options_vec = static_cast<std::vector<BreakpointOptions *> *>(
- io_handler.GetUserData());
- for (auto *bp_options : *bp_options_vec) {
+ auto *bp_options_vec =
+ static_cast<std::vector<std::reference_wrapper<BreakpointOptions>> *>(
+ io_handler.GetUserData());
+ for (BreakpointOptions &bp_options : *bp_options_vec) {
Status error = m_script_interpreter.SetBreakpointCommandCallback(
bp_options, data.c_str());
if (error.Fail())
@@ -108,9 +117,13 @@ public:
}
io_handler.SetIsDone(true);
} break;
- case eIOHandlerWatchpoint:
+ case eIOHandlerWatchpoint: {
+ auto *wp_options =
+ static_cast<WatchpointOptions *>(io_handler.GetUserData());
+ m_script_interpreter.SetWatchpointCommandCallback(wp_options,
+ data.c_str());
io_handler.SetIsDone(true);
- break;
+ } break;
case eIOHandlerNone:
if (IsQuitCommand(data)) {
io_handler.SetIsDone(true);
@@ -133,7 +146,7 @@ ScriptInterpreterLua::ScriptInterpreterLua(Debugger &debugger)
: ScriptInterpreter(debugger, eScriptLanguageLua),
m_lua(std::make_unique<Lua>()) {}
-ScriptInterpreterLua::~ScriptInterpreterLua() {}
+ScriptInterpreterLua::~ScriptInterpreterLua() = default;
bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command,
CommandReturnObject *result,
@@ -194,8 +207,9 @@ void ScriptInterpreterLua::ExecuteInterpreterLoop() {
}
bool ScriptInterpreterLua::LoadScriptingModule(
- const char *filename, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+ const char *filename, const LoadScriptOptions &options,
+ lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
+ FileSpec extra_search_dir) {
FileSystem::Instance().Collect(filename);
if (llvm::Error e = m_lua->LoadModule(filename)) {
@@ -275,8 +289,35 @@ bool ScriptInterpreterLua::BreakpointCallbackFunction(
return *BoolOrErr;
}
+bool ScriptInterpreterLua::WatchpointCallbackFunction(
+ void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
+ assert(context);
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target == nullptr)
+ return true;
+
+ StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
+ WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
+
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreterLua *lua_interpreter = static_cast<ScriptInterpreterLua *>(
+ debugger.GetScriptInterpreter(true, eScriptLanguageLua));
+ Lua &lua = lua_interpreter->GetLua();
+
+ llvm::Expected<bool> BoolOrErr =
+ lua.CallWatchpointCallback(baton, stop_frame_sp, wp_sp);
+ if (llvm::Error E = BoolOrErr.takeError()) {
+ debugger.GetErrorStream() << toString(std::move(E));
+ return true;
+ }
+
+ return *BoolOrErr;
+}
+
void ScriptInterpreterLua::CollectDataForBreakpointCommandCallback(
- std::vector<BreakpointOptions *> &bp_options_vec,
+ std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
CommandReturnObject &result) {
IOHandlerSP io_handler_sp(
new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerBreakpoint));
@@ -284,8 +325,16 @@ void ScriptInterpreterLua::CollectDataForBreakpointCommandCallback(
m_debugger.RunIOHandlerAsync(io_handler_sp);
}
+void ScriptInterpreterLua::CollectDataForWatchpointCommandCallback(
+ WatchpointOptions *wp_options, CommandReturnObject &result) {
+ IOHandlerSP io_handler_sp(
+ new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerWatchpoint));
+ io_handler_sp->SetUserData(wp_options);
+ m_debugger.RunIOHandlerAsync(io_handler_sp);
+}
+
Status ScriptInterpreterLua::SetBreakpointCommandCallbackFunction(
- BreakpointOptions *bp_options, const char *function_name,
+ BreakpointOptions &bp_options, const char *function_name,
StructuredData::ObjectSP extra_args_sp) {
const char *fmt_str = "return {0}(frame, bp_loc, ...)";
std::string oneliner = llvm::formatv(fmt_str, function_name).str();
@@ -294,12 +343,12 @@ Status ScriptInterpreterLua::SetBreakpointCommandCallbackFunction(
}
Status ScriptInterpreterLua::SetBreakpointCommandCallback(
- BreakpointOptions *bp_options, const char *command_body_text) {
+ BreakpointOptions &bp_options, const char *command_body_text) {
return RegisterBreakpointCallback(bp_options, command_body_text, {});
}
Status ScriptInterpreterLua::RegisterBreakpointCallback(
- BreakpointOptions *bp_options, const char *command_body_text,
+ BreakpointOptions &bp_options, const char *command_body_text,
StructuredData::ObjectSP extra_args_sp) {
Status error;
auto data_up = std::make_unique<CommandDataLua>(extra_args_sp);
@@ -308,7 +357,27 @@ Status ScriptInterpreterLua::RegisterBreakpointCallback(
return error;
auto baton_sp =
std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
- bp_options->SetCallback(ScriptInterpreterLua::BreakpointCallbackFunction,
+ bp_options.SetCallback(ScriptInterpreterLua::BreakpointCallbackFunction,
+ baton_sp);
+ return error;
+}
+
+void ScriptInterpreterLua::SetWatchpointCommandCallback(
+ WatchpointOptions *wp_options, const char *command_body_text) {
+ RegisterWatchpointCallback(wp_options, command_body_text, {});
+}
+
+Status ScriptInterpreterLua::RegisterWatchpointCallback(
+ WatchpointOptions *wp_options, const char *command_body_text,
+ StructuredData::ObjectSP extra_args_sp) {
+ Status error;
+ auto data_up = std::make_unique<WatchpointOptions::CommandData>();
+ error = m_lua->RegisterWatchpointCallback(data_up.get(), command_body_text);
+ if (error.Fail())
+ return error;
+ auto baton_sp =
+ std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
+ wp_options->SetCallback(ScriptInterpreterLua::WatchpointCallbackFunction,
baton_sp);
return error;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
index 1130ceee3c20..808000b833ec 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -9,6 +9,9 @@
#ifndef liblldb_ScriptInterpreterLua_h_
#define liblldb_ScriptInterpreterLua_h_
+#include <vector>
+
+#include "lldb/Breakpoint/WatchpointOptions.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Utility/Status.h"
@@ -40,7 +43,8 @@ public:
void ExecuteInterpreterLoop() override;
- bool LoadScriptingModule(const char *filename, bool init_session,
+ bool LoadScriptingModule(const char *filename,
+ const LoadScriptOptions &options,
lldb_private::Status &error,
StructuredData::ObjectSP *module_sp = nullptr,
FileSpec extra_search_dir = {}) override;
@@ -61,6 +65,10 @@ public:
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
+ static bool WatchpointCallbackFunction(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t watch_id);
+
// PluginInterface protocol
lldb_private::ConstString GetPluginName() override;
@@ -72,21 +80,32 @@ public:
llvm::Error LeaveSession();
void CollectDataForBreakpointCommandCallback(
- std::vector<BreakpointOptions *> &bp_options_vec,
+ std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
CommandReturnObject &result) override;
- Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+ void
+ CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
+ CommandReturnObject &result) override;
+
+ Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
const char *command_body_text) override;
+ void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
+ const char *command_body_text) override;
+
Status SetBreakpointCommandCallbackFunction(
- BreakpointOptions *bp_options, const char *function_name,
+ BreakpointOptions &bp_options, const char *function_name,
StructuredData::ObjectSP extra_args_sp) override;
private:
std::unique_ptr<Lua> m_lua;
bool m_session_is_active = false;
- Status RegisterBreakpointCallback(BreakpointOptions *bp_options,
+ Status RegisterBreakpointCallback(BreakpointOptions &bp_options,
+ const char *command_body_text,
+ StructuredData::ObjectSP extra_args_sp);
+
+ Status RegisterWatchpointCallback(WatchpointOptions *wp_options,
const char *command_body_text,
StructuredData::ObjectSP extra_args_sp);
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index d9c32cc132d4..f8a385240bd9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -25,7 +25,7 @@ LLDB_PLUGIN_DEFINE(ScriptInterpreterNone)
ScriptInterpreterNone::ScriptInterpreterNone(Debugger &debugger)
: ScriptInterpreter(debugger, eScriptLanguageNone) {}
-ScriptInterpreterNone::~ScriptInterpreterNone() {}
+ScriptInterpreterNone::~ScriptInterpreterNone() = default;
bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command,
CommandReturnObject *,
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 7c49502f1b57..f51d9b3a796c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -24,7 +24,7 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Errno.h"
-#include <stdio.h>
+#include <cstdio>
using namespace lldb_private;
using namespace lldb;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 22f6c67eb7a5..4577253227cd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -229,7 +229,7 @@ struct PythonFormat<
class PythonObject {
public:
- PythonObject() : m_py_obj(nullptr) {}
+ PythonObject() = default;
PythonObject(PyRefType type, PyObject *py_obj) {
m_py_obj = py_obj;
@@ -378,7 +378,7 @@ public:
}
protected:
- PyObject *m_py_obj;
+ PyObject *m_py_obj = nullptr;
};
@@ -421,7 +421,7 @@ public:
Py_DECREF(py_obj);
}
- TypedPythonObject() {}
+ TypedPythonObject() = default;
};
class PythonBytes : public TypedPythonObject<PythonBytes> {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
index 5f6429f5cd0e..95a3365ed983 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
@@ -2,7 +2,7 @@
#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
-#include <stdio.h>
+#include <cstdio>
#include <editline/readline.h>
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
new file mode 100644
index 000000000000..7c7c5d73680a
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
@@ -0,0 +1,48 @@
+//===-- SWIGPythonBridge.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Config.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
+#include "SWIGPythonBridge.h"
+
+using namespace lldb;
+
+namespace lldb_private {
+
+template <typename T> const char *GetPythonValueFormatString(T t);
+template <> const char *GetPythonValueFormatString(char *) { return "s"; }
+template <> const char *GetPythonValueFormatString(char) { return "b"; }
+template <> const char *GetPythonValueFormatString(unsigned char) {
+ return "B";
+}
+template <> const char *GetPythonValueFormatString(short) { return "h"; }
+template <> const char *GetPythonValueFormatString(unsigned short) {
+ return "H";
+}
+template <> const char *GetPythonValueFormatString(int) { return "i"; }
+template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
+template <> const char *GetPythonValueFormatString(long) { return "l"; }
+template <> const char *GetPythonValueFormatString(unsigned long) {
+ return "k";
+}
+template <> const char *GetPythonValueFormatString(long long) { return "L"; }
+template <> const char *GetPythonValueFormatString(unsigned long long) {
+ return "K";
+}
+template <> const char *GetPythonValueFormatString(float) { return "f"; }
+template <> const char *GetPythonValueFormatString(double) { return "d"; }
+
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
new file mode 100644
index 000000000000..1ef792bcf303
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -0,0 +1,56 @@
+//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
+
+#include <string>
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+
+// GetPythonValueFormatString provides a system independent type safe way to
+// convert a variable's type into a python value format. Python value formats
+// are defined in terms of builtin C types and could change from system to as
+// the underlying typedef for uint* types, size_t, off_t and other values
+// change.
+
+template <typename T> const char *GetPythonValueFormatString(T t);
+template <> const char *GetPythonValueFormatString(char *);
+template <> const char *GetPythonValueFormatString(char);
+template <> const char *GetPythonValueFormatString(unsigned char);
+template <> const char *GetPythonValueFormatString(short);
+template <> const char *GetPythonValueFormatString(unsigned short);
+template <> const char *GetPythonValueFormatString(int);
+template <> const char *GetPythonValueFormatString(unsigned int);
+template <> const char *GetPythonValueFormatString(long);
+template <> const char *GetPythonValueFormatString(unsigned long);
+template <> const char *GetPythonValueFormatString(long long);
+template <> const char *GetPythonValueFormatString(unsigned long long);
+template <> const char *GetPythonValueFormatString(float t);
+template <> const char *GetPythonValueFormatString(double t);
+
+extern "C" void *LLDBSwigPythonCreateScriptedProcess(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl,
+ std::string &error_string);
+
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
+
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 6b53bd3a2edc..7ad63722c31c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -16,7 +16,11 @@
#include "PythonDataObjects.h"
#include "PythonReadline.h"
+#include "SWIGPythonBridge.h"
#include "ScriptInterpreterPythonImpl.h"
+#include "ScriptedProcessPythonInterface.h"
+
+#include "lldb/API/SBError.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBValue.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
@@ -41,10 +45,10 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatAdapters.h"
+#include <cstdio>
+#include <cstdlib>
#include <memory>
#include <mutex>
-#include <stdio.h>
-#include <stdlib.h>
#include <string>
using namespace lldb;
@@ -148,8 +152,6 @@ extern "C" void *LLDBSwigPython_GetChildAtIndex(void *implementor,
extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor,
const char *child_name);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
-
extern lldb::ValueObjectSP
LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
@@ -234,8 +236,7 @@ namespace {
// save off initial state at the beginning, and restore it at the end
struct InitializePythonRAII {
public:
- InitializePythonRAII()
- : m_gil_state(PyGILState_UNLOCKED), m_was_already_initialized(false) {
+ InitializePythonRAII() {
InitializePythonHome();
#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
@@ -355,8 +356,8 @@ private:
}
TerminalState m_stdin_tty_state;
- PyGILState_STATE m_gil_state;
- bool m_was_already_initialized;
+ PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
+ bool m_was_already_initialized = false;
};
} // namespace
@@ -410,6 +411,32 @@ FileSpec ScriptInterpreterPython::GetPythonDir() {
return g_spec;
}
+void ScriptInterpreterPython::SharedLibraryDirectoryHelper(
+ FileSpec &this_file) {
+ // When we're loaded from python, this_file will point to the file inside the
+ // python package directory. Replace it with the one in the lib directory.
+#ifdef _WIN32
+ // On windows, we need to manually back out of the python tree, and go into
+ // the bin directory. This is pretty much the inverse of what ComputePythonDir
+ // does.
+ if (this_file.GetFileNameExtension() == ConstString(".pyd")) {
+ this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd
+ this_file.RemoveLastPathComponent(); // lldb
+ llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
+ for (auto it = llvm::sys::path::begin(libdir),
+ end = llvm::sys::path::end(libdir);
+ it != end; ++it)
+ this_file.RemoveLastPathComponent();
+ this_file.AppendPathComponent("bin");
+ this_file.AppendPathComponent("liblldb.dll");
+ }
+#else
+ // The python file is a symlink, so we can find the real library by resolving
+ // it. We can do this unconditionally.
+ FileSystem::Instance().ResolveSymbolicLink(this_file, this_file);
+#endif
+}
+
lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() {
static ConstString g_name("script-python");
return g_name;
@@ -506,6 +533,9 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_command_thread_state(nullptr) {
InitializePrivate();
+ m_scripted_process_interface_up =
+ std::make_unique<ScriptedProcessPythonInterface>(*this);
+
m_dictionary_name.append("_dict");
StreamString run_string;
run_string.Printf("%s = dict()", m_dictionary_name.c_str());
@@ -605,11 +635,10 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
case eIOHandlerNone:
break;
case eIOHandlerBreakpoint: {
- std::vector<BreakpointOptions *> *bp_options_vec =
- (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
- for (auto bp_options : *bp_options_vec) {
- if (!bp_options)
- continue;
+ std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
+ (std::vector<std::reference_wrapper<BreakpointOptions>> *)
+ io_handler.GetUserData();
+ for (BreakpointOptions &bp_options : *bp_options_vec) {
auto data_up = std::make_unique<CommandDataPython>();
if (!data_up)
@@ -623,7 +652,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
.Success()) {
auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
std::move(data_up));
- bp_options->SetCallback(
+ bp_options.SetCallback(
ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
} else if (!batch_mode) {
StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
@@ -1048,11 +1077,24 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
void *ret_value, const ExecuteScriptOptions &options) {
+ llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+ io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+ options.GetEnableIO(), m_debugger, /*result=*/nullptr);
+
+ if (!io_redirect_or_error) {
+ llvm::consumeError(io_redirect_or_error.takeError());
+ return false;
+ }
+
+ ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
+
Locker locker(this,
Locker::AcquireLock | Locker::InitSession |
(options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
Locker::NoSTDIN,
- Locker::FreeAcquiredLock | Locker::TearDownSession);
+ Locker::FreeAcquiredLock | Locker::TearDownSession,
+ io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
+ io_redirect.GetErrorFile());
PythonModule &main_module = GetMainModule();
PythonDictionary globals = main_module.GetDictionary();
@@ -1161,11 +1203,22 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
if (in_string == nullptr)
return Status();
+ llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+ io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+ options.GetEnableIO(), m_debugger, /*result=*/nullptr);
+
+ if (!io_redirect_or_error)
+ return Status(io_redirect_or_error.takeError());
+
+ ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
+
Locker locker(this,
Locker::AcquireLock | Locker::InitSession |
(options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
Locker::NoSTDIN,
- Locker::FreeAcquiredLock | Locker::TearDownSession);
+ Locker::FreeAcquiredLock | Locker::TearDownSession,
+ io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
+ io_redirect.GetErrorFile());
PythonModule &main_module = GetMainModule();
PythonDictionary globals = main_module.GetDictionary();
@@ -1196,7 +1249,7 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
}
void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
- std::vector<BreakpointOptions *> &bp_options_vec,
+ std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
CommandReturnObject &result) {
m_active_io_handler = eIOHandlerBreakpoint;
m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
@@ -1211,7 +1264,7 @@ void ScriptInterpreterPythonImpl::CollectDataForWatchpointCommandCallback(
}
Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction(
- BreakpointOptions *bp_options, const char *function_name,
+ BreakpointOptions &bp_options, const char *function_name,
StructuredData::ObjectSP extra_args_sp) {
Status error;
// For now just cons up a oneliner that calls the provided function.
@@ -1253,7 +1306,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction(
}
Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
- BreakpointOptions *bp_options,
+ BreakpointOptions &bp_options,
std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
Status error;
error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
@@ -1264,21 +1317,20 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
}
auto baton_sp =
std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
- bp_options->SetCallback(
+ bp_options.SetCallback(
ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
return error;
}
Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
- BreakpointOptions *bp_options, const char *command_body_text) {
+ BreakpointOptions &bp_options, const char *command_body_text) {
return SetBreakpointCommandCallback(bp_options, command_body_text, {},false);
}
// Set a Python one-liner as the callback for the breakpoint.
Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
- BreakpointOptions *bp_options, const char *command_body_text,
- StructuredData::ObjectSP extra_args_sp,
- bool uses_extra_args) {
+ BreakpointOptions &bp_options, const char *command_body_text,
+ StructuredData::ObjectSP extra_args_sp, bool uses_extra_args) {
auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
// Split the command_body_text into lines, and pass that to
// GenerateBreakpointCommandCallbackData. That will wrap the body in an
@@ -1292,7 +1344,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
if (error.Success()) {
auto baton_sp =
std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
- bp_options->SetCallback(
+ bp_options.SetCallback(
ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
return error;
}
@@ -1330,7 +1382,7 @@ Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter(
Status error = ExecuteMultipleLines(
function_def_string.c_str(),
- ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
+ ExecuteScriptOptions().SetEnableIO(false));
return error;
}
@@ -1678,35 +1730,6 @@ StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
return StructuredData::ArraySP();
}
-// GetPythonValueFormatString provides a system independent type safe way to
-// convert a variable's type into a python value format. Python value formats
-// are defined in terms of builtin C types and could change from system to as
-// the underlying typedef for uint* types, size_t, off_t and other values
-// change.
-
-template <typename T> const char *GetPythonValueFormatString(T t);
-template <> const char *GetPythonValueFormatString(char *) { return "s"; }
-template <> const char *GetPythonValueFormatString(char) { return "b"; }
-template <> const char *GetPythonValueFormatString(unsigned char) {
- return "B";
-}
-template <> const char *GetPythonValueFormatString(short) { return "h"; }
-template <> const char *GetPythonValueFormatString(unsigned short) {
- return "H";
-}
-template <> const char *GetPythonValueFormatString(int) { return "i"; }
-template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
-template <> const char *GetPythonValueFormatString(long) { return "l"; }
-template <> const char *GetPythonValueFormatString(unsigned long) {
- return "k";
-}
-template <> const char *GetPythonValueFormatString(long long) { return "L"; }
-template <> const char *GetPythonValueFormatString(unsigned long long) {
- return "K";
-}
-template <> const char *GetPythonValueFormatString(float t) { return "f"; }
-template <> const char *GetPythonValueFormatString(double t) { return "d"; }
-
StructuredData::StringSP
ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
@@ -2058,7 +2081,10 @@ ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
StructuredData::ObjectSP module_sp;
- if (LoadScriptingModule(file_spec.GetPath().c_str(), true, error, &module_sp))
+ LoadScriptOptions load_script_options =
+ LoadScriptOptions().SetInitSession(true).SetSilent(false);
+ if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options,
+ error, &module_sp))
return module_sp;
return StructuredData::ObjectSP();
@@ -2733,26 +2759,44 @@ uint64_t replace_all(std::string &str, const std::string &oldStr,
}
bool ScriptInterpreterPythonImpl::LoadScriptingModule(
- const char *pathname, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+ const char *pathname, const LoadScriptOptions &options,
+ lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
+ FileSpec extra_search_dir) {
namespace fs = llvm::sys::fs;
namespace path = llvm::sys::path;
+ ExecuteScriptOptions exc_options = ExecuteScriptOptions()
+ .SetEnableIO(!options.GetSilent())
+ .SetSetLLDBGlobals(false);
+
if (!pathname || !pathname[0]) {
error.SetErrorString("invalid pathname");
return false;
}
+ llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+ io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+ exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr);
+
+ if (!io_redirect_or_error) {
+ error = io_redirect_or_error.takeError();
+ return false;
+ }
+
+ ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
// Before executing Python code, lock the GIL.
Locker py_lock(this,
Locker::AcquireLock |
- (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN,
+ (options.GetInitSession() ? Locker::InitSession : 0) |
+ Locker::NoSTDIN,
Locker::FreeAcquiredLock |
- (init_session ? Locker::TearDownSession : 0));
+ (options.GetInitSession() ? Locker::TearDownSession : 0),
+ io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
+ io_redirect.GetErrorFile());
- auto ExtendSysPath = [this](std::string directory) -> llvm::Error {
+ auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
if (directory.empty()) {
return llvm::make_error<llvm::StringError>(
"invalid directory name", llvm::inconvertibleErrorCode());
@@ -2767,11 +2811,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
"sys.path.insert(1,'%s');\n\n",
directory.c_str(), directory.c_str());
bool syspath_retval =
- ExecuteMultipleLines(command_stream.GetData(),
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false))
- .Success();
+ ExecuteMultipleLines(command_stream.GetData(), exc_options).Success();
if (!syspath_retval) {
return llvm::make_error<llvm::StringError>(
"Python sys.path handling failed", llvm::inconvertibleErrorCode());
@@ -2781,6 +2821,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
};
std::string module_name(pathname);
+ bool possible_package = false;
if (extra_search_dir) {
if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
@@ -2805,6 +2846,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
return false;
}
// Not a filename, probably a package of some sort, let it go through.
+ possible_package = true;
} else if (is_directory(st) || is_regular_file(st)) {
if (module_file.GetDirectory().IsEmpty()) {
error.SetErrorString("invalid directory name");
@@ -2831,35 +2873,39 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
module_name.resize(module_name.length() - 4);
}
- // check if the module is already import-ed
+ if (!possible_package && module_name.find('.') != llvm::StringRef::npos) {
+ error.SetErrorStringWithFormat(
+ "Python does not allow dots in module names: %s", module_name.c_str());
+ return false;
+ }
+
+ if (module_name.find('-') != llvm::StringRef::npos) {
+ error.SetErrorStringWithFormat(
+ "Python discourages dashes in module names: %s", module_name.c_str());
+ return false;
+ }
+
+ // Check if the module is already imported.
StreamString command_stream;
command_stream.Clear();
command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
bool does_contain = false;
- // this call will succeed if the module was ever imported in any Debugger
- // in the lifetime of the process in which this LLDB framework is living
- bool was_imported_globally =
- (ExecuteOneLineWithReturn(
- command_stream.GetData(),
- ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false)) &&
- does_contain);
- // this call will fail if the module was not imported in this Debugger
- // before
- command_stream.Clear();
- command_stream.Printf("sys.getrefcount(%s)", module_name.c_str());
- bool was_imported_locally = GetSessionDictionary()
- .GetItemForKey(PythonString(module_name))
- .IsAllocated();
-
- bool was_imported = (was_imported_globally || was_imported_locally);
+ // This call will succeed if the module was ever imported in any Debugger in
+ // the lifetime of the process in which this LLDB framework is living.
+ const bool does_contain_executed = ExecuteOneLineWithReturn(
+ command_stream.GetData(),
+ ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, exc_options);
+
+ const bool was_imported_globally = does_contain_executed && does_contain;
+ const bool was_imported_locally =
+ GetSessionDictionary()
+ .GetItemForKey(PythonString(module_name))
+ .IsAllocated();
// now actually do the import
command_stream.Clear();
- if (was_imported) {
+ if (was_imported_globally || was_imported_locally) {
if (!was_imported_locally)
command_stream.Printf("import %s ; reload_module(%s)",
module_name.c_str(), module_name.c_str());
@@ -2868,10 +2914,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
} else
command_stream.Printf("import %s", module_name.c_str());
- error = ExecuteMultipleLines(command_stream.GetData(),
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false));
+ error = ExecuteMultipleLines(command_stream.GetData(), exc_options);
if (error.Fail())
return false;
@@ -2890,7 +2933,8 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
void *module_pyobj = nullptr;
if (ExecuteOneLineWithReturn(
command_stream.GetData(),
- ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj) &&
+ ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj,
+ exc_options) &&
module_pyobj)
*module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
}
@@ -3047,7 +3091,7 @@ bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item,
if (ExecuteOneLineWithReturn(
command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
&result_ptr,
- ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) {
+ ExecuteScriptOptions().SetEnableIO(false))) {
if (result_ptr)
dest.assign(result_ptr);
return true;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index e59fedbd0971..b8b978118218 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -13,6 +13,8 @@
#if LLDB_ENABLE_PYTHON
+#include "ScriptedProcessPythonInterface.h"
+
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/StructuredDataImpl.h"
@@ -51,6 +53,7 @@ public:
static lldb_private::ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
static FileSpec GetPythonDir();
+ static void SharedLibraryDirectoryHelper(FileSpec &this_file);
protected:
static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 45dad4217005..d1b0b3fda1ef 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
+
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_PYTHON
@@ -231,7 +234,8 @@ public:
bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
std::string &output, Status &error) override;
- bool LoadScriptingModule(const char *filename, bool init_session,
+ bool LoadScriptingModule(const char *filename,
+ const LoadScriptOptions &options,
lldb_private::Status &error,
StructuredData::ObjectSP *module_sp = nullptr,
FileSpec extra_search_dir = {}) override;
@@ -241,7 +245,7 @@ public:
std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
void CollectDataForBreakpointCommandCallback(
- std::vector<BreakpointOptions *> &bp_options_vec,
+ std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
CommandReturnObject &result) override;
void
@@ -249,20 +253,19 @@ public:
CommandReturnObject &result) override;
/// Set the callback body text into the callback for the breakpoint.
- Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+ Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
const char *callback_body) override;
Status SetBreakpointCommandCallbackFunction(
- BreakpointOptions *bp_options,
- const char *function_name,
+ BreakpointOptions &bp_options, const char *function_name,
StructuredData::ObjectSP extra_args_sp) override;
/// This one is for deserialization:
Status SetBreakpointCommandCallback(
- BreakpointOptions *bp_options,
+ BreakpointOptions &bp_options,
std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
- Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+ Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
const char *command_body_text,
StructuredData::ObjectSP extra_args_sp,
bool uses_extra_args);
@@ -416,7 +419,7 @@ public:
: IOHandler(debugger, IOHandler::Type::PythonInterpreter),
m_python(python) {}
- ~IOHandlerPythonInterpreter() override {}
+ ~IOHandlerPythonInterpreter() override = default;
ConstString GetControlSequence(char ch) override {
if (ch == 'd')
@@ -483,4 +486,5 @@ protected:
} // namespace lldb_private
-#endif
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
new file mode 100644
index 000000000000..ce262c930f8b
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -0,0 +1,306 @@
+//===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Config.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
+#include "SWIGPythonBridge.h"
+#include "ScriptInterpreterPythonImpl.h"
+#include "ScriptedProcessPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
+ const llvm::StringRef class_name, lldb::TargetSP target_sp,
+ StructuredData::DictionarySP args_sp) {
+ if (class_name.empty())
+ return {};
+
+ std::string error_string;
+ StructuredDataImpl *args_impl = nullptr;
+ if (args_sp) {
+ args_impl = new StructuredDataImpl();
+ args_impl->SetObjectSP(args_sp);
+ }
+
+ void *ret_val;
+
+ {
+
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ ret_val = LLDBSwigPythonCreateScriptedProcess(
+ class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
+ args_impl, error_string);
+ }
+
+ m_object_instance_sp =
+ StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+
+ return m_object_instance_sp;
+}
+
+Status ScriptedProcessPythonInterface::Launch() {
+ return GetStatusFromMethod("launch");
+}
+
+Status ScriptedProcessPythonInterface::Resume() {
+ return GetStatusFromMethod("resume");
+}
+
+bool ScriptedProcessPythonInterface::ShouldStop() {
+ llvm::Optional<unsigned long long> should_stop =
+ GetGenericInteger("should_stop");
+
+ if (!should_stop)
+ return false;
+
+ return static_cast<bool>(*should_stop);
+}
+
+Status ScriptedProcessPythonInterface::Stop() {
+ return GetStatusFromMethod("stop");
+}
+
+Status ScriptedProcessPythonInterface::GetStatusFromMethod(
+ llvm::StringRef method_name) {
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ if (!m_object_instance_sp)
+ return Status("Python object ill-formed.");
+
+ if (!m_object_instance_sp)
+ return Status("Cannot convert Python object to StructuredData::Generic.");
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)m_object_instance_sp->GetValue());
+
+ if (!implementor.IsAllocated())
+ return Status("Python implementor not allocated.");
+
+ PythonObject pmeth(
+ PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return Status("Python method not allocated.");
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return Status("Python method not callable.");
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ PythonObject py_return(PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(),
+ method_name.str().c_str(),
+ nullptr));
+
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ return Status("Python method could not be called.");
+ }
+
+ if (PyObject *py_ret_ptr = py_return.get()) {
+ lldb::SBError *sb_error =
+ (lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr);
+
+ if (!sb_error)
+ return Status("Couldn't cast lldb::SBError to lldb::Status.");
+
+ Status status = m_interpreter.GetStatusFromSBError(*sb_error);
+
+ if (status.Fail())
+ return Status("error: %s", status.AsCString());
+
+ return status;
+ }
+
+ return Status("Returned object is null.");
+}
+
+llvm::Optional<unsigned long long>
+ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) {
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ if (!m_object_instance_sp)
+ return llvm::None;
+
+ if (!m_object_instance_sp)
+ return llvm::None;
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)m_object_instance_sp->GetValue());
+
+ if (!implementor.IsAllocated())
+ return llvm::None;
+
+ PythonObject pmeth(
+ PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return llvm::None;
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return llvm::None;
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ PythonObject py_return(PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(),
+ method_name.str().c_str(),
+ nullptr));
+
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (!py_return.get())
+ return llvm::None;
+
+ llvm::Expected<unsigned long long> size = py_return.AsUnsignedLongLong();
+ // FIXME: Handle error.
+ if (!size)
+ return llvm::None;
+
+ return *size;
+}
+
+lldb::MemoryRegionInfoSP
+ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
+ lldb::addr_t address) {
+ // TODO: Implement
+ return nullptr;
+}
+
+StructuredData::DictionarySP
+ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
+ // TODO: Implement
+ return nullptr;
+}
+
+StructuredData::DictionarySP
+ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
+ // TODO: Implement
+ return nullptr;
+}
+
+lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
+ lldb::addr_t address, size_t size, Status &error) {
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ auto error_with_message = [&error](llvm::StringRef message) {
+ error.SetErrorString(message);
+ return nullptr;
+ };
+
+ static char callee_name[] = "read_memory_at_address";
+ std::string param_format = GetPythonValueFormatString(address);
+ param_format += GetPythonValueFormatString(size);
+
+ if (!m_object_instance_sp)
+ return error_with_message("Python object ill-formed.");
+
+ if (!m_object_instance_sp)
+ return error_with_message("Python method not callable.");
+
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)m_object_instance_sp->GetValue());
+
+ if (!implementor.IsAllocated())
+ return error_with_message("Python implementor not allocated.");
+
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return error_with_message("Python method not allocated.");
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return error_with_message("Python method not callable.");
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ PythonObject py_return(PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name,
+ param_format.c_str(), address,
+ size));
+
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ return error_with_message("Python method could not be called.");
+ }
+
+ if (PyObject *py_ret_ptr = py_return.get()) {
+ lldb::SBData *sb_data =
+ (lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr);
+
+ if (!sb_data)
+ return error_with_message(
+ "Couldn't cast lldb::SBData to lldb::DataExtractor.");
+
+ return m_interpreter.GetDataExtractorFromSBData(*sb_data);
+ }
+
+ return error_with_message("Returned object is null.");
+}
+
+StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
+ // TODO: Implement
+ return nullptr;
+}
+
+lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
+ llvm::Optional<unsigned long long> pid = GetGenericInteger("get_process_id");
+ return (!pid) ? LLDB_INVALID_PROCESS_ID : *pid;
+}
+
+bool ScriptedProcessPythonInterface::IsAlive() {
+ llvm::Optional<unsigned long long> is_alive = GetGenericInteger("is_alive");
+
+ if (!is_alive)
+ return false;
+
+ return static_cast<bool>(*is_alive);
+}
+
+#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
new file mode 100644
index 000000000000..30cb5a882af2
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -0,0 +1,66 @@
+//===-- ScriptedProcessPythonInterface.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "lldb/Interpreter/ScriptedProcessInterface.h"
+
+namespace lldb_private {
+class ScriptInterpreterPythonImpl;
+class ScriptedProcessPythonInterface : public ScriptedProcessInterface {
+public:
+ ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter)
+ : ScriptedProcessInterface(), m_interpreter(interpreter) {}
+
+ StructuredData::GenericSP
+ CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp,
+ StructuredData::DictionarySP args_sp) override;
+
+ Status Launch() override;
+
+ Status Resume() override;
+
+ bool ShouldStop() override;
+
+ Status Stop() override;
+
+ lldb::MemoryRegionInfoSP
+ GetMemoryRegionContainingAddress(lldb::addr_t address) override;
+
+ StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override;
+
+ StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) override;
+
+ lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size,
+ Status &error) override;
+
+ StructuredData::DictionarySP GetLoadedImages() override;
+
+ lldb::pid_t GetProcessID() override;
+
+ bool IsAlive() override;
+
+protected:
+ llvm::Optional<unsigned long long>
+ GetGenericInteger(llvm::StringRef method_name);
+ Status GetStatusFromMethod(llvm::StringRef method_name);
+
+private:
+ // The lifetime is managed by the ScriptInterpreter
+ ScriptInterpreterPythonImpl &m_interpreter;
+ StructuredData::GenericSP m_object_instance_sp;
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index f669e5873d2d..87edf7789f0d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -8,7 +8,7 @@
#include "StructuredDataDarwinLog.h"
-#include <string.h>
+#include <cstring>
#include <memory>
#include <sstream>
@@ -126,7 +126,7 @@ public:
m_collection_sp->Initialize(g_darwinlog_properties);
}
- ~StructuredDataDarwinLogProperties() override {}
+ ~StructuredDataDarwinLogProperties() override = default;
bool GetEnableOnStartup() const {
const uint32_t idx = ePropertyEnableOnStartup;
@@ -181,7 +181,7 @@ using FilterRuleSP = std::shared_ptr<FilterRule>;
class FilterRule {
public:
- virtual ~FilterRule() {}
+ virtual ~FilterRule() = default;
using OperationCreationFunc =
std::function<FilterRuleSP(bool accept, size_t attribute_index,
@@ -473,13 +473,9 @@ static constexpr OptionDefinition g_enable_option_table[] = {
class EnableOptions : public Options {
public:
EnableOptions()
- : Options(), m_include_debug_level(false), m_include_info_level(false),
- m_include_any_process(false),
+ : Options(),
m_filter_fall_through_accepts(DEFAULT_FILTER_FALLTHROUGH_ACCEPTS),
- m_echo_to_stderr(false), m_display_timestamp_relative(false),
- m_display_subsystem(false), m_display_category(false),
- m_display_activity_chain(false), m_broadcast_events(true),
- m_live_stream(true), m_filter_rules() {}
+ m_filter_rules() {}
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_include_debug_level = false;
@@ -728,17 +724,17 @@ private:
return -1;
}
- bool m_include_debug_level;
- bool m_include_info_level;
- bool m_include_any_process;
+ bool m_include_debug_level = false;
+ bool m_include_info_level = false;
+ bool m_include_any_process = false;
bool m_filter_fall_through_accepts;
- bool m_echo_to_stderr;
- bool m_display_timestamp_relative;
- bool m_display_subsystem;
- bool m_display_category;
- bool m_display_activity_chain;
- bool m_broadcast_events;
- bool m_live_stream;
+ bool m_echo_to_stderr = false;
+ bool m_display_timestamp_relative = false;
+ bool m_display_subsystem = false;
+ bool m_display_category = false;
+ bool m_display_activity_chain = false;
+ bool m_broadcast_events = true;
+ bool m_live_stream = true;
FilterRules m_filter_rules;
};
@@ -813,7 +809,6 @@ protected:
StructuredDataDarwinLog::GetStaticPluginName())) {
result.AppendError("failed to get StructuredDataPlugin for "
"the process");
- result.SetStatus(eReturnStatusFailed);
}
StructuredDataDarwinLog &plugin =
*static_cast<StructuredDataDarwinLog *>(plugin_sp.get());
@@ -837,7 +832,6 @@ protected:
// Report results.
if (!error.Success()) {
result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
// Our configuration failed, so we're definitely disabled.
plugin.SetEnabled(false);
} else {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index 07e5b284eab8..b815ebb3c07a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -278,7 +278,7 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
}
uint32_t SymbolFileBreakpad::ResolveSymbolContext(
- const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ const SourceLocationSpec &src_location_spec,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!(resolve_scope & eSymbolContextCompUnit))
@@ -287,8 +287,7 @@ uint32_t SymbolFileBreakpad::ResolveSymbolContext(
uint32_t old_size = sc_list.GetSize();
for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) {
CompileUnit &cu = *GetCompileUnitAtIndex(i);
- cu.ResolveSymbolContext(file_spec, line, check_inlines,
- /*exact*/ false, resolve_scope, sc_list);
+ cu.ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
}
return sc_list.GetSize() - old_size;
}
@@ -716,10 +715,10 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
llvm::Optional<addr_t> next_addr;
auto finish_sequence = [&]() {
LineTable::AppendLineEntryToSequence(
- line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0,
- /*file_idx*/ 0, /*is_start_of_statement*/ false,
- /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
- /*is_epilogue_begin*/ false, /*is_terminal_entry*/ true);
+ line_seq_up.get(), *next_addr, /*line=*/0, /*column=*/0,
+ /*file_idx=*/0, /*is_start_of_statement=*/false,
+ /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false,
+ /*is_epilogue_begin=*/false, /*is_terminal_entry=*/true);
sequences.push_back(std::move(line_seq_up));
line_seq_up = LineTable::CreateLineSequenceContainer();
};
@@ -739,10 +738,10 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
finish_sequence();
}
LineTable::AppendLineEntryToSequence(
- line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0,
- map[record->FileNum], /*is_start_of_statement*/ true,
- /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
- /*is_epilogue_begin*/ false, /*is_terminal_entry*/ false);
+ line_seq_up.get(), record->Address, record->LineNum, /*column=*/0,
+ map[record->FileNum], /*is_start_of_statement=*/true,
+ /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false,
+ /*is_epilogue_begin=*/false, /*is_terminal_entry=*/false);
next_addr = record->Address + record->Size;
}
if (next_addr)
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 90dbcc77627a..b0a35fa11de4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -51,7 +51,7 @@ public:
SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)
: SymbolFile(std::move(objfile_sp)) {}
- ~SymbolFileBreakpad() override {}
+ ~SymbolFileBreakpad() override = default;
uint32_t CalculateAbilities() override;
@@ -101,8 +101,7 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContext &sc) override;
- uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line,
- bool check_inlines,
+ uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 2e0a7fd3ecd3..ffe24836955f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -24,7 +24,7 @@ class SymbolFileDWARF;
class DWARFASTParser {
public:
- virtual ~DWARFASTParser() {}
+ virtual ~DWARFASTParser() = default;
virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
const DWARFDIE &die,
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 188a667ca564..46015f7b43b1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stdlib.h>
+#include <cstdlib>
#include "DWARFASTParserClang.h"
#include "DWARFDebugInfo.h"
@@ -49,7 +49,7 @@
//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
@@ -60,7 +60,7 @@ using namespace lldb_private;
DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast)
: m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
-DWARFASTParserClang::~DWARFASTParserClang() {}
+DWARFASTParserClang::~DWARFASTParserClang() = default;
static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) {
switch (dwarf_accessibility) {
@@ -157,7 +157,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
// The type in the Clang module must have the same language as the current CU.
LanguageSet languages;
- languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU()));
+ languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
llvm::DenseSet<SymbolFile *> searched_symbol_files;
clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages,
searched_symbol_files, pcm_types);
@@ -666,8 +666,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
// Blocks have a __FuncPtr inside them which is a pointer to a
// function of the proper type.
- for (DWARFDIE child_die = target_die.GetFirstChild();
- child_die.IsValid(); child_die = child_die.GetSibling()) {
+ for (DWARFDIE child_die : target_die.children()) {
if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
"__FuncPtr")) {
DWARFDIE function_pointer_type =
@@ -1226,6 +1225,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
}
if (!function_decl) {
+ char *name_buf = nullptr;
llvm::StringRef name = attrs.name.GetStringRef();
// We currently generate function templates with template parameters in
@@ -1233,8 +1233,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
// we want to strip these from the name when creating the AST.
if (attrs.mangled_name) {
llvm::ItaniumPartialDemangler D;
- if (!D.partialDemangle(attrs.mangled_name))
- name = D.getFunctionBaseName(nullptr, nullptr);
+ if (!D.partialDemangle(attrs.mangled_name)) {
+ name_buf = D.getFunctionBaseName(nullptr, nullptr);
+ name = name_buf;
+ }
}
// We just have a function that isn't part of a class
@@ -1243,6 +1245,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
: containing_decl_ctx,
GetOwningClangModule(die), name, clang_type, attrs.storage,
attrs.is_inline);
+ std::free(name_buf);
if (has_template_params) {
TypeSystemClang::TemplateParameterInfos template_param_infos;
@@ -1266,13 +1269,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
LinkDeclContextToDIE(function_decl, die);
if (!function_param_decls.empty()) {
- m_ast.SetFunctionParameters(function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
+ m_ast.SetFunctionParameters(function_decl, function_param_decls);
if (template_function_decl)
m_ast.SetFunctionParameters(template_function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
+ function_param_decls);
}
ClangASTMetadata metadata;
@@ -1357,7 +1357,7 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true);
CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
- CompilerType class_clang_type = class_type->GetLayoutCompilerType();
+ CompilerType class_clang_type = class_type->GetForwardCompilerType();
CompilerType clang_type = TypeSystemClang::CreateMemberPointerType(
class_clang_type, pointee_clang_type);
@@ -1684,14 +1684,18 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
die.GetOffset(), attrs.name.GetCString());
}
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
+ // If the byte size of the record is specified then overwrite the size
+ // that would be computed by Clang. This is only needed as LLDB's
+ // TypeSystemClang is always in C++ mode, but some compilers such as
+ // GCC and Clang give empty structs a size of 0 in C mode (in contrast to
+ // the size of 1 for empty structs that would be computed in C++ mode).
+ if (attrs.byte_size) {
clang::RecordDecl *record_decl =
TypeSystemClang::GetAsRecordDecl(clang_type);
-
if (record_decl) {
- GetClangASTImporter().SetRecordLayout(
- record_decl, ClangASTImporter::LayoutInfo());
+ ClangASTImporter::LayoutInfo layout;
+ layout.bit_size = *attrs.byte_size * 8;
+ GetClangASTImporter().SetRecordLayout(record_decl, layout);
}
}
} else if (clang_type_was_created) {
@@ -1822,8 +1826,7 @@ bool DWARFASTParserClang::ParseTemplateDIE(
case DW_TAG_GNU_template_parameter_pack: {
template_param_infos.packed_args =
std::make_unique<TypeSystemClang::TemplateParameterInfos>();
- for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
- child_die = child_die.GetSibling()) {
+ for (DWARFDIE child_die : die.children()) {
if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args))
return false;
}
@@ -1928,8 +1931,7 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
if (!parent_die)
return false;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
switch (tag) {
@@ -1978,15 +1980,12 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
}
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
- std::vector<int> member_accessibilities;
- bool is_a_class = false;
// Parse members and base classes first
std::vector<DWARFDIE> member_function_dies;
DelayedPropertyList delayed_properties;
- ParseChildMembers(die, clang_type, bases, member_accessibilities,
- member_function_dies, delayed_properties,
- default_accessibility, is_a_class, layout_info);
+ ParseChildMembers(die, clang_type, bases, member_function_dies,
+ delayed_properties, default_accessibility, layout_info);
// Now parse any methods if there were any...
for (const DWARFDIE &die : member_function_dies)
@@ -2007,31 +2006,6 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
}
}
- // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
- // need to tell the clang type it is actually a class.
- if (!type_is_objc_object_or_interface) {
- if (is_a_class && tag_decl_kind != clang::TTK_Class)
- m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type),
- clang::TTK_Class);
- }
-
- // Since DW_TAG_structure_type gets used for both classes and
- // structures, we may need to set any DW_TAG_member fields to have a
- // "private" access if none was specified. When we parsed the child
- // members we tracked that actual accessibility value for each
- // DW_TAG_member in the "member_accessibilities" array. If the value
- // for the member is zero, then it was set to the
- // "default_accessibility" which for structs was "public". Below we
- // correct this by setting any fields to "private" that weren't
- // correctly set.
- if (is_a_class && !member_accessibilities.empty()) {
- // This is a class and all members that didn't have their access
- // specified are private.
- m_ast.SetDefaultAccessForRecordFields(
- m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
- &member_accessibilities.front(), member_accessibilities.size());
- }
-
if (!bases.empty()) {
// Make sure all base classes refer to complete types and not forward
// declarations. If we don't do this, clang will crash with an
@@ -2131,8 +2105,7 @@ void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(
for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);
it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;
it = m_decl_ctx_to_die.erase(it))
- for (DWARFDIE decl = it->second.GetFirstChild(); decl;
- decl = decl.GetSibling())
+ for (DWARFDIE decl : it->second.children())
GetClangDeclForDIE(decl);
}
@@ -2168,8 +2141,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
size_t enumerators_added = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
if (tag == DW_TAG_enumerator) {
DWARFAttributes attributes;
@@ -2201,7 +2173,8 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
case DW_AT_description:
default:
case DW_AT_decl_file:
- decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
+ decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile(
+ form_value.Unsigned()));
break;
case DW_AT_decl_line:
decl.SetLine(form_value.Unsigned());
@@ -2343,7 +2316,6 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
void DWARFASTParserClang::ParseSingleMember(
const DWARFDIE &die, const DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
- std::vector<int> &member_accessibilities,
lldb::AccessType default_accessibility,
DelayedPropertyList &delayed_properties,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
@@ -2533,7 +2505,7 @@ void DWARFASTParserClang::ParseSingleMember(
if (accessibility == eAccessNone)
accessibility = eAccessPublic;
TypeSystemClang::AddVariableToRecordType(
- class_clang_type, name, var_type->GetLayoutCompilerType(),
+ class_clang_type, name, var_type->GetForwardCompilerType(),
accessibility);
}
return;
@@ -2551,7 +2523,6 @@ void DWARFASTParserClang::ParseSingleMember(
if (accessibility == eAccessNone)
accessibility = default_accessibility;
- member_accessibilities.push_back(accessibility);
uint64_t field_bit_offset =
(member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
@@ -2666,7 +2637,7 @@ void DWARFASTParserClang::ParseSingleMember(
last_field_info.bit_offset = field_bit_offset;
if (llvm::Optional<uint64_t> clang_type_size =
- member_clang_type.GetByteSize(nullptr)) {
+ member_type->GetByteSize(nullptr)) {
last_field_info.bit_size = *clang_type_size * character_width;
}
@@ -2761,10 +2732,9 @@ void DWARFASTParserClang::ParseSingleMember(
bool DWARFASTParserClang::ParseChildMembers(
const DWARFDIE &parent_die, CompilerType &class_clang_type,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
- std::vector<int> &member_accessibilities,
std::vector<DWARFDIE> &member_function_dies,
DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
- bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
+ ClangASTImporter::LayoutInfo &layout_info) {
if (!parent_die)
return false;
@@ -2776,16 +2746,15 @@ bool DWARFASTParserClang::ParseChildMembers(
if (ast == nullptr)
return false;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
dw_tag_t tag = die.Tag();
switch (tag) {
case DW_TAG_member:
case DW_TAG_APPLE_property:
ParseSingleMember(die, parent_die, class_clang_type,
- member_accessibilities, default_accessibility,
- delayed_properties, layout_info, last_field_info);
+ default_accessibility, delayed_properties, layout_info,
+ last_field_info);
break;
case DW_TAG_subprogram:
@@ -2794,9 +2763,6 @@ bool DWARFASTParserClang::ParseChildMembers(
break;
case DW_TAG_inheritance: {
- is_a_class = true;
- if (default_accessibility == eAccessNone)
- default_accessibility = eAccessPrivate;
// TODO: implement DW_TAG_inheritance type parsing
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
@@ -2926,8 +2892,7 @@ size_t DWARFASTParserClang::ParseChildParameters(
return 0;
size_t arg_idx = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
switch (tag) {
case DW_TAG_formal_parameter: {
@@ -3046,8 +3011,7 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
if (!parent_die)
return llvm::None;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
if (tag != DW_TAG_subrange_type)
continue;
@@ -3349,8 +3313,7 @@ static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) {
}
static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) {
- for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid();
- candidate = candidate.GetSibling()) {
+ for (DWARFDIE candidate : context.children()) {
if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
return candidate;
}
@@ -3514,8 +3477,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
UniqueCStringMap<DWARFDIE> dst_name_to_die;
UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
- for (src_die = src_class_die.GetFirstChild(); src_die.IsValid();
- src_die = src_die.GetSibling()) {
+ for (DWARFDIE src_die : src_class_die.children()) {
if (src_die.Tag() == DW_TAG_subprogram) {
// Make sure this is a declaration and not a concrete instance by looking
// for DW_AT_declaration set to 1. Sometimes concrete function instances
@@ -3533,8 +3495,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
}
}
}
- for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
- dst_die = dst_die.GetSibling()) {
+ for (DWARFDIE dst_die : dst_class_die.children()) {
if (dst_die.Tag() == DW_TAG_subprogram) {
// Make sure this is a declaration and not a concrete instance by looking
// for DW_AT_declaration set to 1. Sometimes concrete function instances
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index e13716b95c1c..9bf6240b7554 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -111,10 +111,9 @@ protected:
bool ParseChildMembers(
const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
- std::vector<int> &member_accessibilities,
std::vector<DWARFDIE> &member_function_dies,
DelayedPropertyList &delayed_properties,
- lldb::AccessType &default_accessibility, bool &is_a_class,
+ lldb::AccessType &default_accessibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
@@ -194,7 +193,6 @@ private:
void
ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
- std::vector<int> &member_accessibilities,
lldb::AccessType default_accessibility,
DelayedPropertyList &delayed_properties,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index 0e9370be15fb..2f6b36c79b80 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -17,9 +17,7 @@
using namespace lldb_private;
-DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
- : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0),
- m_attributes() {}
+DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : m_attributes() {}
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
uint8_t has_children)
@@ -58,7 +56,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
DWARFFormValue::ValueType val;
if (form == DW_FORM_implicit_const)
- val.value.sval = data.GetULEB128(offset_ptr);
+ val.value.sval = data.GetSLEB128(offset_ptr);
m_attributes.push_back(DWARFAttribute(attr, form, val));
}
@@ -82,9 +80,3 @@ DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
}
return DW_INVALID_INDEX;
}
-
-bool DWARFAbbreviationDeclaration::
-operator==(const DWARFAbbreviationDeclaration &rhs) const {
- return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
- m_attributes == rhs.m_attributes;
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
index f70aa71a5958..378ba888f4e0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -53,12 +53,11 @@ public:
extract(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
bool IsValid();
- bool operator==(const DWARFAbbreviationDeclaration &rhs) const;
protected:
- dw_uleb128_t m_code;
- dw_tag_t m_tag;
- uint8_t m_has_children;
+ dw_uleb128_t m_code = InvalidCode;
+ dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
+ uint8_t m_has_children = 0;
DWARFAttribute::collection m_attributes;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index ef98d7e33a90..134f6b2bd114 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -12,7 +12,7 @@
DWARFAttributes::DWARFAttributes() : m_infos() {}
-DWARFAttributes::~DWARFAttributes() {}
+DWARFAttributes::~DWARFAttributes() = default;
uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
collection::const_iterator end = m_infos.end();
@@ -25,10 +25,11 @@ uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
return UINT32_MAX;
}
-void DWARFAttributes::Append(DWARFUnit *cu, dw_offset_t attr_die_offset,
- dw_attr_t attr, dw_form_t form) {
- AttributeValue attr_value = {
- cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}};
+void DWARFAttributes::Append(const DWARFFormValue &form_value,
+ dw_offset_t attr_die_offset, dw_attr_t attr) {
+ AttributeValue attr_value = {const_cast<DWARFUnit *>(form_value.GetUnit()),
+ attr_die_offset,
+ {attr, form_value.Form(), form_value.Value()}};
m_infos.push_back(attr_value);
}
@@ -37,6 +38,10 @@ bool DWARFAttributes::ExtractFormValueAtIndex(
const DWARFUnit *cu = CompileUnitAtIndex(i);
form_value.SetUnit(cu);
form_value.SetForm(FormAtIndex(i));
+ if (form_value.Form() == DW_FORM_implicit_const) {
+ form_value.SetValue(ValueAtIndex(i));
+ return true;
+ }
lldb::offset_t offset = DIEOffsetAtIndex(i);
return form_value.ExtractValue(cu->GetData(), &offset);
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index 8c21404610d7..a31ee861179c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -22,21 +22,15 @@ public:
DWARFFormValue::ValueType value)
: m_attr(attr), m_form(form), m_value(value) {}
- void set(dw_attr_t attr, dw_form_t form) {
- m_attr = attr;
- m_form = form;
- }
dw_attr_t get_attr() const { return m_attr; }
dw_form_t get_form() const { return m_form; }
+ DWARFFormValue::ValueType get_value() const { return m_value; }
void get(dw_attr_t &attr, dw_form_t &form,
DWARFFormValue::ValueType &val) const {
attr = m_attr;
form = m_form;
val = m_value;
}
- bool operator==(const DWARFAttribute &rhs) const {
- return m_attr == rhs.m_attr && m_form == rhs.m_form;
- }
typedef std::vector<DWARFAttribute> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
@@ -52,8 +46,8 @@ public:
DWARFAttributes();
~DWARFAttributes();
- void Append(DWARFUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr,
- dw_form_t form);
+ void Append(const DWARFFormValue &form_value, dw_offset_t attr_die_offset,
+ dw_attr_t attr);
DWARFUnit *CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; }
dw_offset_t DIEOffsetAtIndex(uint32_t i) const {
return m_infos[i].die_offset;
@@ -62,6 +56,9 @@ public:
return m_infos[i].attr.get_attr();
}
dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); }
+ DWARFFormValue::ValueType ValueAtIndex(uint32_t i) const {
+ return m_infos[i].attr.get_value();
+ }
bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const;
DWARFDIE FormValueAsReferenceAtIndex(uint32_t i) const;
DWARFDIE FormValueAsReference(dw_attr_t attr) const;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 059b84864be7..36df980f6ef0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -24,7 +24,7 @@ class SymbolFileDWARF;
class DWARFBaseDIE {
public:
- DWARFBaseDIE() : m_cu(nullptr), m_die(nullptr) {}
+ DWARFBaseDIE() = default;
DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die)
: m_cu(cu), m_die(die) {}
@@ -115,8 +115,8 @@ public:
Recurse recurse = Recurse::yes) const;
protected:
- DWARFUnit *m_cu;
- DWARFDebugInfoEntry *m_die;
+ DWARFUnit *m_cu = nullptr;
+ DWARFDebugInfoEntry *m_die = nullptr;
};
bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 8e995e627978..dda691eecacc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -54,7 +54,7 @@ public:
explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {}
/// End marker
- ElaboratingDIEIterator() {}
+ ElaboratingDIEIterator() = default;
const DWARFDIE &operator*() const { return m_worklist.back(); }
ElaboratingDIEIterator &operator++() {
@@ -192,7 +192,7 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
}
if (check_children) {
- for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) {
+ for (DWARFDIE child : children()) {
if (DWARFDIE child_result = child.LookupDeepestBlock(address))
return child_result;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 13737280926c..56154055c44d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -11,9 +11,11 @@
#include "DWARFBaseDIE.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/iterator_range.h"
class DWARFDIE : public DWARFBaseDIE {
public:
+ class child_iterator;
using DWARFBaseDIE::DWARFBaseDIE;
// Tests
@@ -88,6 +90,47 @@ public:
int &decl_line, int &decl_column, int &call_file,
int &call_line, int &call_column,
lldb_private::DWARFExpression *frame_base) const;
+ /// The range of all the children of this DIE.
+ ///
+ /// This is a template just because child_iterator is not completely defined
+ /// at this point.
+ template <typename T = child_iterator>
+ llvm::iterator_range<T> children() const {
+ return llvm::make_range(T(*this), T());
+ }
+};
+
+class DWARFDIE::child_iterator
+ : public llvm::iterator_facade_base<DWARFDIE::child_iterator,
+ std::forward_iterator_tag, DWARFDIE> {
+ /// The current child or an invalid DWARFDie.
+ DWARFDIE m_die;
+
+public:
+ child_iterator() = default;
+ child_iterator(const DWARFDIE &parent) : m_die(parent.GetFirstChild()) {}
+ bool operator==(const child_iterator &it) const {
+ // DWARFDIE's operator== differentiates between an invalid DWARFDIE that
+ // has a CU but no DIE and one that has neither CU nor DIE. The 'end'
+ // iterator could be default constructed, so explicitly allow
+ // (CU, (DIE)nullptr) == (nullptr, nullptr) -> true
+ if (!m_die.IsValid() && !it.m_die.IsValid())
+ return true;
+ return m_die == it.m_die;
+ }
+ const DWARFDIE &operator*() const {
+ assert(m_die.IsValid() && "Derefencing invalid iterator?");
+ return m_die;
+ }
+ DWARFDIE &operator*() {
+ assert(m_die.IsValid() && "Derefencing invalid iterator?");
+ return m_die;
+ }
+ child_iterator &operator++() {
+ assert(m_die.IsValid() && "Incrementing invalid iterator?");
+ m_die = m_die.GetSibling();
+ return *this;
+ }
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 555864f44967..ec6b93ce0e7f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -26,8 +26,7 @@ typedef DWARFAbbreviationDeclarationColl::const_iterator
class DWARFAbbreviationDeclarationSet {
public:
- DWARFAbbreviationDeclarationSet()
- : m_offset(DW_INVALID_OFFSET), m_idx_offset(0), m_decls() {}
+ DWARFAbbreviationDeclarationSet() : m_offset(DW_INVALID_OFFSET), m_decls() {}
DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset)
: m_offset(offset), m_idx_offset(idx_offset), m_decls() {}
@@ -51,7 +50,7 @@ public:
/// @}
private:
dw_offset_t m_offset;
- uint32_t m_idx_offset;
+ uint32_t m_idx_offset = 0;
std::vector<DWARFAbbreviationDeclaration> m_decls;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
index 728cefe620a5..ce514381ee39 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -8,22 +8,18 @@
#include "DWARFDebugArangeSet.h"
#include "DWARFDataExtractor.h"
+#include "LogChannelDWARF.h"
#include "llvm/Object/Error.h"
#include <cassert>
using namespace lldb_private;
DWARFDebugArangeSet::DWARFDebugArangeSet()
- : m_offset(DW_INVALID_OFFSET), m_header(), m_arange_descriptors() {
- m_header.length = 0;
- m_header.version = 0;
- m_header.cu_offset = 0;
- m_header.addr_size = 0;
- m_header.seg_size = 0;
-}
+ : m_offset(DW_INVALID_OFFSET), m_next_offset(DW_INVALID_OFFSET) {}
void DWARFDebugArangeSet::Clear() {
m_offset = DW_INVALID_OFFSET;
+ m_next_offset = DW_INVALID_OFFSET;
m_header.length = 0;
m_header.version = 0;
m_header.cu_offset = 0;
@@ -54,6 +50,12 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
// consists of an address and a length, each in the size appropriate for an
// address on the target architecture.
m_header.length = data.GetDWARFInitialLength(offset_ptr);
+ // The length could be 4 bytes or 12 bytes, so use the current offset to
+ // determine the next offset correctly.
+ if (m_header.length > 0)
+ m_next_offset = *offset_ptr + m_header.length;
+ else
+ m_next_offset = DW_INVALID_OFFSET;
m_header.version = data.GetU16(offset_ptr);
m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
m_header.addr_size = data.GetU8(offset_ptr);
@@ -105,17 +107,45 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
"DWARFDebugArangeSet::Descriptor.address and "
"DWARFDebugArangeSet::Descriptor.length must have same size");
- while (data.ValidOffset(*offset_ptr)) {
+ const lldb::offset_t next_offset = GetNextOffset();
+ assert(next_offset != DW_INVALID_OFFSET);
+ uint32_t num_terminators = 0;
+ bool last_was_terminator = false;
+ while (*offset_ptr < next_offset) {
arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size);
arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size);
// Each set of tuples is terminated by a 0 for the address and 0 for
- // the length.
- if (!arangeDescriptor.address && !arangeDescriptor.length)
- return llvm::ErrorSuccess();
-
- m_arange_descriptors.push_back(arangeDescriptor);
+ // the length. Some linkers can emit .debug_aranges with multiple
+ // terminator pair entries that are still withing the length of the
+ // DWARFDebugArangeSet. We want to be sure to parse all entries for
+ // this DWARFDebugArangeSet so that we don't stop parsing early and end up
+ // treating addresses as a header of the next DWARFDebugArangeSet. We also
+ // need to make sure we parse all valid address pairs so we don't omit them
+ // from the aranges result, so we can't stop at the first terminator entry
+ // we find.
+ if (arangeDescriptor.address == 0 && arangeDescriptor.length == 0) {
+ ++num_terminators;
+ last_was_terminator = true;
+ } else {
+ last_was_terminator = false;
+ // Only add .debug_aranges address entries that have a non zero size.
+ // Some linkers will zero out the length field for some .debug_aranges
+ // entries if they were stripped. We also could watch out for multiple
+ // entries at address zero and remove those as well.
+ if (arangeDescriptor.length > 0)
+ m_arange_descriptors.push_back(arangeDescriptor);
+ }
+ }
+ if (num_terminators > 1) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG(log,
+ "warning: DWARFDebugArangeSet at %#" PRIx64 " contains %u "
+ "terminator entries",
+ m_offset, num_terminators);
}
+ if (last_was_terminator)
+ return llvm::ErrorSuccess();
return llvm::make_error<llvm::object::GenericBinaryError>(
"arange descriptors not terminated by null entry");
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
index 6b5b69a70a80..3c8633eaa3cc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -16,18 +16,21 @@
class DWARFDebugArangeSet {
public:
struct Header {
- uint32_t length; // The total length of the entries for that set, not
- // including the length field itself.
- uint16_t version; // The DWARF version number
- uint32_t cu_offset; // The offset from the beginning of the .debug_info
- // section of the compilation unit entry referenced by
- // the table.
- uint8_t addr_size; // The size in bytes of an address on the target
- // architecture. For segmented addressing, this is the
- // size of the offset portion of the address
- uint8_t seg_size; // The size in bytes of a segment descriptor on the target
- // architecture. If the target system uses a flat address
- // space, this value is 0.
+ /// The total length of the entries for that set, not including the length
+ /// field itself.
+ uint32_t length = 0;
+ /// The DWARF version number.
+ uint16_t version = 0;
+ /// The offset from the beginning of the .debug_info section of the
+ /// compilation unit entry referenced by the table.
+ uint32_t cu_offset = 0;
+ /// The size in bytes of an address on the target architecture. For
+ /// segmented addressing, this is the size of the offset portion of the
+ /// address.
+ uint8_t addr_size = 0;
+ /// The size in bytes of a segment descriptor on the target architecture.
+ /// If the target system uses a flat address space, this value is 0.
+ uint8_t seg_size = 0;
};
struct Descriptor {
@@ -44,7 +47,7 @@ public:
dw_offset_t FindAddress(dw_addr_t address) const;
size_t NumDescriptors() const { return m_arange_descriptors.size(); }
const Header &GetHeader() const { return m_header; }
-
+ dw_offset_t GetNextOffset() const { return m_next_offset; }
const Descriptor &GetDescriptorRef(uint32_t i) const {
return m_arange_descriptors[i];
}
@@ -54,7 +57,8 @@ protected:
typedef DescriptorColl::iterator DescriptorIter;
typedef DescriptorColl::const_iterator DescriptorConstIter;
- uint32_t m_offset;
+ dw_offset_t m_offset;
+ dw_offset_t m_next_offset;
Header m_header;
DescriptorColl m_arange_descriptors;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index 9f190fbcee87..65923cb4ad6b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -9,6 +9,7 @@
#include "DWARFDebugAranges.h"
#include "DWARFDebugArangeSet.h"
#include "DWARFUnit.h"
+#include "LogChannelDWARF.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
@@ -31,31 +32,40 @@ public:
};
// Extract
-llvm::Error
-DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
+void DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
lldb::offset_t offset = 0;
DWARFDebugArangeSet set;
Range range;
while (debug_aranges_data.ValidOffset(offset)) {
- llvm::Error error = set.extract(debug_aranges_data, &offset);
- if (error)
- return error;
+ const lldb::offset_t set_offset = offset;
+ if (llvm::Error error = set.extract(debug_aranges_data, &offset)) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, std::move(error),
+ "DWARFDebugAranges::extract failed to extract "
+ ".debug_aranges set at offset %#" PRIx64,
+ set_offset);
+ } else {
+ const uint32_t num_descriptors = set.NumDescriptors();
+ if (num_descriptors > 0) {
+ const dw_offset_t cu_offset = set.GetHeader().cu_offset;
- const uint32_t num_descriptors = set.NumDescriptors();
- if (num_descriptors > 0) {
- const dw_offset_t cu_offset = set.GetHeader().cu_offset;
-
- for (uint32_t i = 0; i < num_descriptors; ++i) {
- const DWARFDebugArangeSet::Descriptor &descriptor =
- set.GetDescriptorRef(i);
- m_aranges.Append(RangeToDIE::Entry(descriptor.address,
- descriptor.length, cu_offset));
+ for (uint32_t i = 0; i < num_descriptors; ++i) {
+ const DWARFDebugArangeSet::Descriptor &descriptor =
+ set.GetDescriptorRef(i);
+ m_aranges.Append(RangeToDIE::Entry(descriptor.address,
+ descriptor.length, cu_offset));
+ }
}
}
+ // Always use the previous DWARFDebugArangeSet's information to calculate
+ // the offset of the next DWARFDebugArangeSet in case we entouncter an
+ // error in the current DWARFDebugArangeSet and our offset position is
+ // still in the middle of the data. If we do this, we can parse all valid
+ // DWARFDebugArangeSet objects without returning invalid errors.
+ offset = set.GetNextOffset();
set.Clear();
}
- return llvm::ErrorSuccess();
}
void DWARFDebugAranges::Dump(Log *log) const {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
index 96e82619f985..5ff37e400c88 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -26,8 +26,7 @@ public:
void Clear() { m_aranges.Clear(); }
- llvm::Error
- extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
+ void extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
// Use append range multiple times and then call sort
void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 8d393b295443..e43afa104413 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -34,17 +34,18 @@ DWARFDebugInfo::DWARFDebugInfo(SymbolFileDWARF &dwarf,
lldb_private::DWARFContext &context)
: m_dwarf(dwarf), m_context(context), m_units(), m_cu_aranges_up() {}
-llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
+const DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() {
if (m_cu_aranges_up)
return *m_cu_aranges_up;
m_cu_aranges_up = std::make_unique<DWARFDebugAranges>();
const DWARFDataExtractor &debug_aranges_data =
m_context.getOrLoadArangesData();
- if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data))
- return std::move(error);
- // Make a list of all CUs represented by the arange data in the file.
+ // Extract what we can from the .debug_aranges first.
+ m_cu_aranges_up->extract(debug_aranges_data);
+
+ // Make a list of all CUs represented by the .debug_aranges data.
std::set<dw_offset_t> cus_with_data;
for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) {
dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n);
@@ -52,8 +53,7 @@ llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
cus_with_data.insert(offset);
}
- // Manually build arange data for everything that wasn't in the
- // .debug_aranges table.
+ // Manually build arange data for everything that wasn't in .debug_aranges.
const size_t num_units = GetNumUnits();
for (size_t idx = 0; idx < num_units; ++idx) {
DWARFUnit *cu = GetUnitAtIndex(idx);
@@ -72,16 +72,10 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
DWARFDataExtractor data = section == DIERef::Section::DebugTypes
? m_context.getOrLoadDebugTypesData()
: m_context.getOrLoadDebugInfoData();
- const llvm::DWARFUnitIndex *index = nullptr;
- if (m_context.isDwo())
- index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(),
- section == DIERef::Section::DebugTypes
- ? llvm::DW_SECT_EXT_TYPES
- : llvm::DW_SECT_INFO);
lldb::offset_t offset = 0;
while (data.ValidOffset(offset)) {
llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
- m_dwarf, m_units.size(), data, section, &offset, index);
+ m_dwarf, m_units.size(), data, section, &offset);
if (!unit_sp) {
// FIXME: Propagate this error up.
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index bdc718a5c2fa..46c04d749c46 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -54,7 +54,7 @@ public:
(1 << 2) // Show all parent DIEs when dumping single DIEs
};
- llvm::Expected<DWARFDebugAranges &> GetCompileUnitAranges();
+ const DWARFDebugAranges &GetCompileUnitAranges();
protected:
typedef std::vector<DWARFUnitSP> UnitColl;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 421298802645..39915aa889ff 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -8,7 +8,7 @@
#include "DWARFDebugInfoEntry.h"
-#include <assert.h>
+#include <cassert>
#include <algorithm>
@@ -49,156 +49,159 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
// assert (fixed_form_sizes); // For best performance this should be
// specified!
- if (m_abbr_idx) {
- lldb::offset_t offset = *offset_ptr;
- const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
- if (abbrevDecl == nullptr) {
- cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
- "attach the file at the start of this error message",
- m_offset, (unsigned)abbr_idx);
- // WE can't parse anymore if the DWARF is borked...
- *offset_ptr = UINT32_MAX;
- return false;
- }
- m_tag = abbrevDecl->Tag();
- m_has_children = abbrevDecl->HasChildren();
- // Skip all data in the .debug_info or .debug_types for the attributes
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_form_t form;
- for (i = 0; i < numAttributes; ++i) {
- form = abbrevDecl->GetFormByIndexUnchecked(i);
- llvm::Optional<uint8_t> fixed_skip_size =
- DWARFFormValue::GetFixedSize(form, cu);
- if (fixed_skip_size)
- offset += *fixed_skip_size;
- else {
- bool form_is_indirect = false;
- do {
- form_is_indirect = false;
- uint32_t form_size = 0;
- switch (form) {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info/.debug_types
- case DW_FORM_exprloc:
- case DW_FORM_block:
- form_size = data.GetULEB128(&offset);
- break;
- case DW_FORM_block1:
- form_size = data.GetU8_unchecked(&offset);
- break;
- case DW_FORM_block2:
- form_size = data.GetU16_unchecked(&offset);
- break;
- case DW_FORM_block4:
- form_size = data.GetU32_unchecked(&offset);
- break;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string:
- data.GetCStr(&offset);
- break;
-
- // Compile unit address sized values
- case DW_FORM_addr:
- form_size = cu->GetAddressByteSize();
- break;
- case DW_FORM_ref_addr:
- if (cu->GetVersion() <= 2)
- form_size = cu->GetAddressByteSize();
- else
- form_size = 4;
- break;
-
- // 0 sized form
- case DW_FORM_flag_present:
- form_size = 0;
- break;
-
- // 1 byte values
- case DW_FORM_addrx1:
- case DW_FORM_data1:
- case DW_FORM_flag:
- case DW_FORM_ref1:
- case DW_FORM_strx1:
- form_size = 1;
- break;
-
- // 2 byte values
- case DW_FORM_addrx2:
- case DW_FORM_data2:
- case DW_FORM_ref2:
- case DW_FORM_strx2:
- form_size = 2;
- break;
-
- // 3 byte values
- case DW_FORM_addrx3:
- case DW_FORM_strx3:
- form_size = 3;
- break;
-
- // 4 byte values
- case DW_FORM_addrx4:
- case DW_FORM_data4:
- case DW_FORM_ref4:
- case DW_FORM_strx4:
- form_size = 4;
- break;
-
- // 8 byte values
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- form_size = 8;
- break;
-
- // signed or unsigned LEB 128 values
- case DW_FORM_addrx:
- case DW_FORM_loclistx:
- case DW_FORM_rnglistx:
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- case DW_FORM_strx:
- data.Skip_LEB128(&offset);
- break;
-
- case DW_FORM_indirect:
- form_is_indirect = true;
- form = data.GetULEB128(&offset);
- break;
-
- case DW_FORM_strp:
- case DW_FORM_sec_offset:
- data.GetU32(&offset);
- break;
-
- case DW_FORM_implicit_const:
- form_size = 0;
- break;
-
- default:
- *offset_ptr = m_offset;
- return false;
- }
- offset += form_size;
-
- } while (form_is_indirect);
- }
- }
- *offset_ptr = offset;
- return true;
- } else {
+ if (m_abbr_idx == 0) {
m_tag = llvm::dwarf::DW_TAG_null;
m_has_children = false;
return true; // NULL debug tag entry
}
- return false;
+ lldb::offset_t offset = *offset_ptr;
+ const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
+ if (abbrevDecl == nullptr) {
+ cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
+ "attach the file at the start of this error message",
+ m_offset, (unsigned)abbr_idx);
+ // WE can't parse anymore if the DWARF is borked...
+ *offset_ptr = UINT32_MAX;
+ return false;
+ }
+ m_tag = abbrevDecl->Tag();
+ m_has_children = abbrevDecl->HasChildren();
+ // Skip all data in the .debug_info or .debug_types for the attributes
+ const uint32_t numAttributes = abbrevDecl->NumAttributes();
+ uint32_t i;
+ dw_form_t form;
+ for (i = 0; i < numAttributes; ++i) {
+ form = abbrevDecl->GetFormByIndexUnchecked(i);
+ llvm::Optional<uint8_t> fixed_skip_size =
+ DWARFFormValue::GetFixedSize(form, cu);
+ if (fixed_skip_size)
+ offset += *fixed_skip_size;
+ else {
+ bool form_is_indirect = false;
+ do {
+ form_is_indirect = false;
+ uint32_t form_size = 0;
+ switch (form) {
+ // Blocks if inlined data that have a length field and the data bytes
+ // inlined in the .debug_info/.debug_types
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ form_size = data.GetULEB128(&offset);
+ break;
+ case DW_FORM_block1:
+ form_size = data.GetU8_unchecked(&offset);
+ break;
+ case DW_FORM_block2:
+ form_size = data.GetU16_unchecked(&offset);
+ break;
+ case DW_FORM_block4:
+ form_size = data.GetU32_unchecked(&offset);
+ break;
+
+ // Inlined NULL terminated C-strings
+ case DW_FORM_string:
+ data.GetCStr(&offset);
+ break;
+
+ // Compile unit address sized values
+ case DW_FORM_addr:
+ form_size = cu->GetAddressByteSize();
+ break;
+ case DW_FORM_ref_addr:
+ if (cu->GetVersion() <= 2)
+ form_size = cu->GetAddressByteSize();
+ else
+ form_size = 4;
+ break;
+
+ // 0 sized form
+ case DW_FORM_flag_present:
+ form_size = 0;
+ break;
+
+ // 1 byte values
+ case DW_FORM_addrx1:
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ case DW_FORM_strx1:
+ form_size = 1;
+ break;
+
+ // 2 byte values
+ case DW_FORM_addrx2:
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ case DW_FORM_strx2:
+ form_size = 2;
+ break;
+
+ // 3 byte values
+ case DW_FORM_addrx3:
+ case DW_FORM_strx3:
+ form_size = 3;
+ break;
+
+ // 4 byte values
+ case DW_FORM_addrx4:
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_strx4:
+ form_size = 4;
+ break;
+
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ form_size = 8;
+ break;
+
+ // signed or unsigned LEB 128 values
+ case DW_FORM_addrx:
+ case DW_FORM_loclistx:
+ case DW_FORM_rnglistx:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
+ data.Skip_LEB128(&offset);
+ break;
+
+ case DW_FORM_indirect:
+ form_is_indirect = true;
+ form = data.GetULEB128(&offset);
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_line_strp:
+ case DW_FORM_sec_offset:
+ data.GetU32(&offset);
+ break;
+
+ case DW_FORM_implicit_const:
+ form_size = 0;
+ break;
+
+ default:
+ cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: Unsupported DW_FORM_0x%x, please file a bug and "
+ "attach the file at the start of this error message",
+ m_offset, (unsigned)form);
+ *offset_ptr = m_offset;
+ return false;
+ }
+ offset += form_size;
+
+ } while (form_is_indirect);
+ }
+ }
+ *offset_ptr = offset;
+ return true;
}
static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit,
@@ -211,11 +214,12 @@ static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit,
if (expected_ranges)
return std::move(*expected_ranges);
unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
+ "{0x%8.8x}: DIE has DW_AT_ranges(%s 0x%" PRIx64 ") attribute, but "
"range extraction failed (%s), please file a bug "
"and attach the file at the start of this error message",
- die.GetOffset(), value.Unsigned(),
- toString(expected_ranges.takeError()).c_str());
+ die.GetOffset(),
+ llvm::dwarf::FormEncodingString(value.Form()).str().c_str(),
+ value.Unsigned(), toString(expected_ranges.takeError()).c_str());
return DWARFRangeList();
}
@@ -429,7 +433,7 @@ size_t DWARFDebugInfoEntry::GetAttributes(DWARFUnit *cu,
}
LLVM_FALLTHROUGH;
default:
- attributes.Append(cu, offset, attr, form);
+ attributes.Append(form_value, offset, attr);
break;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 0ba56a0a4161..64e86c71ac09 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -35,8 +35,7 @@ public:
typedef collection::const_iterator const_iterator;
DWARFDebugInfoEntry()
- : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
- m_has_children(false), m_abbr_idx(0), m_tag(llvm::dwarf::DW_TAG_null) {}
+ : m_offset(DW_INVALID_OFFSET), m_sibling_idx(0), m_has_children(false) {}
explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
bool operator==(const DWARFDebugInfoEntry &rhs) const;
@@ -167,14 +166,14 @@ protected:
GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu);
dw_offset_t m_offset; // Offset within the .debug_info/.debug_types
- uint32_t m_parent_idx; // How many to subtract from "this" to get the parent.
- // If zero this die has no parent
+ uint32_t m_parent_idx = 0; // How many to subtract from "this" to get the
+ // parent. If zero this die has no parent
uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling.
// If it is zero, then the DIE doesn't have children, or the
// DWARF claimed it had children but the DIE only contained
// a single NULL terminating child.
m_has_children : 1;
- uint16_t m_abbr_idx;
+ uint16_t m_abbr_idx = 0;
/// A copy of the DW_TAG value so we don't have to go through the compile
/// unit abbrev table
dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 9072b2dc0115..e46694405415 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -23,7 +23,7 @@
class DWARFDeclContext {
public:
struct Entry {
- Entry() : tag(llvm::dwarf::DW_TAG_null), name(nullptr) {}
+ Entry() = default;
Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
bool NameMatches(const Entry &rhs) const {
@@ -37,11 +37,11 @@ public:
// Test operator
explicit operator bool() const { return tag != 0; }
- dw_tag_t tag;
- const char *name;
+ dw_tag_t tag = llvm::dwarf::DW_TAG_null;
+ const char *name = nullptr;
};
- DWARFDeclContext() : m_entries(), m_language(lldb::eLanguageTypeUnknown) {}
+ DWARFDeclContext() : m_entries() {}
void AppendDeclContext(dw_tag_t tag, const char *name) {
m_entries.push_back(Entry(tag, name));
@@ -83,7 +83,7 @@ protected:
typedef std::vector<Entry> collection;
collection m_entries;
mutable std::string m_qualified_name;
- lldb::LanguageType m_language;
+ lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index 1b7102cd7e31..2d0d5cad4612 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -10,7 +10,7 @@
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H
#include "lldb/Core/dwarf.h"
-#include <stdint.h>
+#include <cstdint>
namespace lldb_private {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 305f1cbd2826..4c498705da45 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <assert.h>
+#include <cassert>
#include "lldb/Core/Module.h"
#include "lldb/Core/dwarf.h"
@@ -150,40 +150,40 @@ struct FormSize {
uint8_t valid:1, size:7;
};
static FormSize g_form_sizes[] = {
- {0,0}, // 0x00 unused
- {0,0}, // 0x01 DW_FORM_addr
- {0,0}, // 0x02 unused
- {0,0}, // 0x03 DW_FORM_block2
- {0,0}, // 0x04 DW_FORM_block4
- {1,2}, // 0x05 DW_FORM_data2
- {1,4}, // 0x06 DW_FORM_data4
- {1,8}, // 0x07 DW_FORM_data8
- {0,0}, // 0x08 DW_FORM_string
- {0,0}, // 0x09 DW_FORM_block
- {0,0}, // 0x0a DW_FORM_block1
- {1,1}, // 0x0b DW_FORM_data1
- {1,1}, // 0x0c DW_FORM_flag
- {0,0}, // 0x0d DW_FORM_sdata
- {1,4}, // 0x0e DW_FORM_strp
- {0,0}, // 0x0f DW_FORM_udata
- {0,0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
- // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
- {1,1}, // 0x11 DW_FORM_ref1
- {1,2}, // 0x12 DW_FORM_ref2
- {1,4}, // 0x13 DW_FORM_ref4
- {1,8}, // 0x14 DW_FORM_ref8
- {0,0}, // 0x15 DW_FORM_ref_udata
- {0,0}, // 0x16 DW_FORM_indirect
- {1,4}, // 0x17 DW_FORM_sec_offset
- {0,0}, // 0x18 DW_FORM_exprloc
- {1,0}, // 0x19 DW_FORM_flag_present
- {0,0}, // 0x1a
- {0,0}, // 0x1b
- {0,0}, // 0x1c
- {0,0}, // 0x1d
- {0,0}, // 0x1e
- {0,0}, // 0x1f
- {1,8}, // 0x20 DW_FORM_ref_sig8
+ {0, 0}, // 0x00 unused
+ {0, 0}, // 0x01 DW_FORM_addr
+ {0, 0}, // 0x02 unused
+ {0, 0}, // 0x03 DW_FORM_block2
+ {0, 0}, // 0x04 DW_FORM_block4
+ {1, 2}, // 0x05 DW_FORM_data2
+ {1, 4}, // 0x06 DW_FORM_data4
+ {1, 8}, // 0x07 DW_FORM_data8
+ {0, 0}, // 0x08 DW_FORM_string
+ {0, 0}, // 0x09 DW_FORM_block
+ {0, 0}, // 0x0a DW_FORM_block1
+ {1, 1}, // 0x0b DW_FORM_data1
+ {1, 1}, // 0x0c DW_FORM_flag
+ {0, 0}, // 0x0d DW_FORM_sdata
+ {1, 4}, // 0x0e DW_FORM_strp
+ {0, 0}, // 0x0f DW_FORM_udata
+ {0, 0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes
+ // for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ {1, 1}, // 0x11 DW_FORM_ref1
+ {1, 2}, // 0x12 DW_FORM_ref2
+ {1, 4}, // 0x13 DW_FORM_ref4
+ {1, 8}, // 0x14 DW_FORM_ref8
+ {0, 0}, // 0x15 DW_FORM_ref_udata
+ {0, 0}, // 0x16 DW_FORM_indirect
+ {1, 4}, // 0x17 DW_FORM_sec_offset
+ {0, 0}, // 0x18 DW_FORM_exprloc
+ {1, 0}, // 0x19 DW_FORM_flag_present
+ {0, 0}, // 0x1a DW_FORM_strx (ULEB128)
+ {0, 0}, // 0x1b DW_FORM_addrx (ULEB128)
+ {1, 4}, // 0x1c DW_FORM_ref_sup4
+ {0, 0}, // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64)
+ {1, 16}, // 0x1e DW_FORM_data16
+ {1, 4}, // 0x1f DW_FORM_line_strp
+ {1, 8}, // 0x20 DW_FORM_ref_sig8
};
llvm::Optional<uint8_t>
@@ -286,6 +286,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
// 32 bit for DWARF 32, 64 for DWARF 64
case DW_FORM_sec_offset:
case DW_FORM_strp:
+ case DW_FORM_line_strp:
*offset_ptr += 4;
return true;
@@ -398,7 +399,8 @@ void DWARFFormValue::Dump(Stream &s) const {
case DW_FORM_udata:
s.PutULEB128(uvalue);
break;
- case DW_FORM_strp: {
+ case DW_FORM_strp:
+ case DW_FORM_line_strp: {
const char *dbg_str = AsCString();
if (dbg_str) {
s.QuotedCString(dbg_str);
@@ -606,6 +608,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {
case DW_FORM_flag:
case DW_FORM_sdata:
case DW_FORM_strp:
+ case DW_FORM_line_strp:
case DW_FORM_strx:
case DW_FORM_strx1:
case DW_FORM_strx2:
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index fe6a55520978..9406bcf0c038 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -10,8 +10,8 @@
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H
#include "DWARFDataExtractor.h"
-#include <stddef.h>
#include "llvm/ADT/Optional.h"
+#include <cstddef>
class DWARFUnit;
class SymbolFileDWARF;
@@ -20,14 +20,14 @@ class DWARFDIE;
class DWARFFormValue {
public:
typedef struct ValueTypeTag {
- ValueTypeTag() : value(), data(nullptr) { value.uval = 0; }
+ ValueTypeTag() : value() { value.uval = 0; }
union {
uint64_t uval;
int64_t sval;
const char *cstr;
} value;
- const uint8_t *data;
+ const uint8_t *data = nullptr;
} ValueType;
enum {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index a761dd3daac4..824e43872269 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -236,6 +236,11 @@ void DWARFUnit::ExtractDIEsRWLocked() {
}
if (!m_die_array.empty()) {
+ // The last die cannot have children (if it did, it wouldn't be the last one).
+ // This only makes a difference for malformed dwarf that does not have a
+ // terminating null die.
+ m_die_array.back().SetHasChildren(false);
+
if (m_first_die) {
// Only needed for the assertion.
m_first_die.SetHasChildren(m_die_array.front().HasChildren());
@@ -292,8 +297,7 @@ uint64_t DWARFUnit::GetDWOId() {
// m_die_array_mutex must be already held as read/write.
void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
- llvm::Optional<uint64_t> addr_base, gnu_addr_base, ranges_base,
- gnu_ranges_base;
+ llvm::Optional<uint64_t> addr_base, gnu_addr_base, gnu_ranges_base;
DWARFAttributes attributes;
size_t num_attributes = cu_die.GetAttributes(this, attributes);
@@ -320,8 +324,7 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
SetLoclistsBase(form_value.Unsigned());
break;
case DW_AT_rnglists_base:
- ranges_base = form_value.Unsigned();
- SetRangesBase(*ranges_base);
+ SetRangesBase(form_value.Unsigned());
break;
case DW_AT_str_offsets_base:
SetStrOffsetsBase(form_value.Unsigned());
@@ -482,19 +485,46 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const {
}
void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) {
+ lldbassert(!m_rnglist_table_done);
+
m_ranges_base = ranges_base;
+}
- if (GetVersion() < 5)
- return;
+const llvm::Optional<llvm::DWARFDebugRnglistTable> &
+DWARFUnit::GetRnglistTable() {
+ if (GetVersion() >= 5 && !m_rnglist_table_done) {
+ m_rnglist_table_done = true;
+ if (auto table_or_error =
+ ParseListTableHeader<llvm::DWARFDebugRnglistTable>(
+ m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
+ m_ranges_base, DWARF32))
+ m_rnglist_table = std::move(table_or_error.get());
+ else
+ GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "Failed to extract range list table at offset 0x%" PRIx64 ": %s",
+ m_ranges_base, toString(table_or_error.takeError()).c_str());
+ }
+ return m_rnglist_table;
+}
- if (auto table_or_error = ParseListTableHeader<llvm::DWARFDebugRnglistTable>(
- m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
- ranges_base, DWARF32))
- m_rnglist_table = std::move(table_or_error.get());
- else
- GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
- "Failed to extract range list table at offset 0x%" PRIx64 ": %s",
- ranges_base, toString(table_or_error.takeError()).c_str());
+// This function is called only for DW_FORM_rnglistx.
+llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) {
+ if (!GetRnglistTable())
+ return llvm::createStringError(errc::invalid_argument,
+ "missing or invalid range list table");
+ if (!m_ranges_base)
+ return llvm::createStringError(errc::invalid_argument,
+ "DW_FORM_rnglistx cannot be used without "
+ "DW_AT_rnglists_base for CU at 0x%8.8x",
+ GetOffset());
+ if (llvm::Optional<uint64_t> off = GetRnglistTable()->getOffsetEntry(
+ m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), Index))
+ return *off + m_ranges_base;
+ return llvm::createStringError(
+ errc::invalid_argument,
+ "invalid range list table index %u; OffsetEntryCount is %u, "
+ "DW_AT_rnglists_base is %" PRIu64,
+ Index, GetRnglistTable()->getOffsetEntryCount(), m_ranges_base);
}
void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) {
@@ -784,12 +814,11 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
llvm::Expected<DWARFUnitHeader>
DWARFUnitHeader::extract(const DWARFDataExtractor &data,
- DIERef::Section section, lldb::offset_t *offset_ptr,
- const llvm::DWARFUnitIndex *index) {
+ DIERef::Section section,
+ lldb_private::DWARFContext &context,
+ lldb::offset_t *offset_ptr) {
DWARFUnitHeader header;
header.m_offset = *offset_ptr;
- if (index)
- header.m_index_entry = index->getFromOffset(*offset_ptr);
header.m_length = data.GetDWARFInitialLength(offset_ptr);
header.m_version = data.GetU16(offset_ptr);
if (header.m_version == 5) {
@@ -806,6 +835,16 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
}
+ if (context.isDwo()) {
+ if (header.IsTypeUnit()) {
+ header.m_index_entry =
+ context.GetAsLLVM().getTUIndex().getFromOffset(header.m_offset);
+ } else {
+ header.m_index_entry =
+ context.GetAsLLVM().getCUIndex().getFromOffset(header.m_offset);
+ }
+ }
+
if (header.m_index_entry) {
if (header.m_abbr_offset) {
return llvm::createStringError(
@@ -856,12 +895,11 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
llvm::Expected<DWARFUnitSP>
DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
const DWARFDataExtractor &debug_info,
- DIERef::Section section, lldb::offset_t *offset_ptr,
- const llvm::DWARFUnitIndex *index) {
+ DIERef::Section section, lldb::offset_t *offset_ptr) {
assert(debug_info.ValidOffset(*offset_ptr));
- auto expected_header =
- DWARFUnitHeader::extract(debug_info, section, offset_ptr, index);
+ auto expected_header = DWARFUnitHeader::extract(
+ debug_info, section, dwarf.GetDWARFContext(), offset_ptr);
if (!expected_header)
return expected_header.takeError();
@@ -930,11 +968,11 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
return ranges;
}
- if (!m_rnglist_table)
+ if (!GetRnglistTable())
return llvm::createStringError(errc::invalid_argument,
"missing or invalid range list table");
- auto range_list_or_error = m_rnglist_table->findList(
+ auto range_list_or_error = GetRnglistTable()->findList(
m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), offset);
if (!range_list_or_error)
return range_list_or_error.takeError();
@@ -963,12 +1001,8 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
llvm::Expected<DWARFRangeList>
DWARFUnit::FindRnglistFromIndex(uint32_t index) {
- if (llvm::Optional<uint64_t> offset = GetRnglistOffset(index))
- return FindRnglistFromOffset(*offset);
- if (m_rnglist_table)
- return llvm::createStringError(errc::invalid_argument,
- "invalid range list table index %d", index);
-
- return llvm::createStringError(errc::invalid_argument,
- "missing or invalid range list table");
+ llvm::Expected<uint64_t> maybe_offset = GetRnglistOffset(index);
+ if (!maybe_offset)
+ return maybe_offset.takeError();
+ return FindRnglistFromOffset(*maybe_offset);
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 5739c36bbacb..da79a6aaf64e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -73,7 +73,8 @@ public:
static llvm::Expected<DWARFUnitHeader>
extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section,
- lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index);
+ lldb_private::DWARFContext &dwarf_context,
+ lldb::offset_t *offset_ptr);
};
class DWARFUnit : public lldb_private::UserID {
@@ -84,8 +85,7 @@ public:
static llvm::Expected<DWARFUnitSP>
extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid,
const lldb_private::DWARFDataExtractor &debug_info,
- DIERef::Section section, lldb::offset_t *offset_ptr,
- const llvm::DWARFUnitIndex *index);
+ DIERef::Section section, lldb::offset_t *offset_ptr);
virtual ~DWARFUnit();
bool IsDWOUnit() { return m_is_dwo; }
@@ -235,15 +235,7 @@ public:
/// Return a rangelist's offset based on an index. The index designates
/// an entry in the rangelist table's offset array and is supplied by
/// DW_FORM_rnglistx.
- llvm::Optional<uint64_t> GetRnglistOffset(uint32_t Index) const {
- if (!m_rnglist_table)
- return llvm::None;
- if (llvm::Optional<uint64_t> off = m_rnglist_table->getOffsetEntry(
- m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
- Index))
- return *off + m_ranges_base;
- return llvm::None;
- }
+ llvm::Expected<uint64_t> GetRnglistOffset(uint32_t Index);
llvm::Optional<uint64_t> GetLoclistOffset(uint32_t Index) {
if (!m_loclist_table_header)
@@ -291,6 +283,8 @@ protected:
return &m_die_array[0];
}
+ const llvm::Optional<llvm::DWARFDebugRnglistTable> &GetRnglistTable();
+
SymbolFileDWARF &m_dwarf;
std::shared_ptr<DWARFUnit> m_dwo;
DWARFUnitHeader m_header;
@@ -331,6 +325,7 @@ protected:
dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
llvm::Optional<llvm::DWARFDebugRnglistTable> m_rnglist_table;
+ bool m_rnglist_table_done = false;
llvm::Optional<llvm::DWARFListTableHeader> m_loclist_table_header;
const DIERef::Section m_section;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index d36f2a8bccf7..ce71281db8bd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -130,8 +130,7 @@ DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f,
: die_offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
- : die_base_offset(_die_base_offset), atoms(), atom_mask(0),
- min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
+ : die_base_offset(_die_base_offset), atoms() {
// Define an array of DIE offsets by first defining an array, and then define
// the atom type for the array, in this case we have an array of DIE offsets.
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index ad178fc6a987..efc08e47a280 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -101,9 +101,9 @@ public:
/// DIE offset base so die offsets in hash_data can be CU relative.
dw_offset_t die_base_offset;
AtomArray atoms;
- uint32_t atom_mask;
- size_t min_hash_data_byte_size;
- bool hash_data_has_fixed_byte_size;
+ uint32_t atom_mask = 0;
+ size_t min_hash_data_byte_size = 0;
+ bool hash_data_has_fixed_byte_size = true;
};
class Header : public MappedHash::Header<Prologue> {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index dda599baffeb..1f40d880ea34 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -13,9 +13,11 @@
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/Progress.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ThreadPool.h"
using namespace lldb_private;
@@ -56,6 +58,17 @@ void ManualDWARFIndex::Index() {
if (units_to_index.empty())
return;
+ StreamString module_desc;
+ m_module.GetDescription(module_desc.AsRawOstream(),
+ lldb::eDescriptionLevelBrief);
+
+ // Include 2 passes per unit to index for extracting DIEs from the unit and
+ // indexing the unit, and then 8 extra entries for finalizing each index set.
+ const uint64_t total_progress = units_to_index.size() * 2 + 8;
+ Progress progress(
+ llvm::formatv("Manually indexing DWARF for {0}", module_desc.GetData()),
+ total_progress);
+
std::vector<IndexSet> sets(units_to_index.size());
// Keep memory down by clearing DIEs for any units if indexing
@@ -64,10 +77,12 @@ void ManualDWARFIndex::Index() {
units_to_index.size());
auto parser_fn = [&](size_t cu_idx) {
IndexUnit(*units_to_index[cu_idx], dwp_dwarf, sets[cu_idx]);
+ progress.Increment();
};
- auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) {
+ auto extract_fn = [&](size_t cu_idx) {
clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped();
+ progress.Increment();
};
// Share one thread pool across operations to avoid the overhead of
@@ -92,11 +107,12 @@ void ManualDWARFIndex::Index() {
pool.async(parser_fn, i);
pool.wait();
- auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) {
+ auto finalize_fn = [this, &sets, &progress](NameToDIE(IndexSet::*index)) {
NameToDIE &result = m_set.*index;
for (auto &set : sets)
result.Append(set.*index);
result.Finalize();
+ progress.Increment();
};
pool.async(finalize_fn, &IndexSet::function_basenames);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
index 5aa841cf3d10..a6863f6c9549 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -22,7 +22,7 @@ class NameToDIE {
public:
NameToDIE() : m_map() {}
- ~NameToDIE() {}
+ ~NameToDIE() = default;
void Dump(lldb_private::Stream *s);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 3656c7333f27..ccaf31317d75 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -16,6 +16,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
@@ -74,18 +75,19 @@
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
#include <algorithm>
#include <map>
#include <memory>
-#include <ctype.h>
-#include <string.h>
+#include <cctype>
+#include <cstring>
//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
@@ -238,9 +240,12 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
const size_t number_of_files = prologue.FileNames.size();
for (size_t idx = first_file; idx <= number_of_files; ++idx) {
std::string remapped_file;
- if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style))
- if (!module->RemapSourceFile(llvm::StringRef(*file_path), remapped_file))
+ if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) {
+ if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))
+ remapped_file = *remapped;
+ else
remapped_file = std::move(*file_path);
+ }
// Unconditionally add an entry, so the indices match up.
support_files.EmplaceBack(remapped_file, style);
@@ -358,8 +363,7 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
}
}
- for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
- child_die = child_die.GetSibling()) {
+ for (DWARFDIE child_die : die.children()) {
GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
}
}
@@ -435,7 +439,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
m_fetched_external_modules(false),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
-SymbolFileDWARF::~SymbolFileDWARF() {}
+SymbolFileDWARF::~SymbolFileDWARF() = default;
static ConstString GetDWARFMachOSegmentName() {
static ConstString g_dwarf_section_name("__DWARF");
@@ -467,22 +471,32 @@ void SymbolFileDWARF::InitializeObject() {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) {
+ StreamString module_desc;
+ GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
+ lldb::eDescriptionLevelBrief);
DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;
LoadSectionData(eSectionTypeDWARFAppleNames, apple_names);
LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces);
LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types);
LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc);
- m_index = AppleDWARFIndex::Create(
- *GetObjectFile()->GetModule(), apple_names, apple_namespaces,
- apple_types, apple_objc, m_context.getOrLoadStrData());
+ if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 ||
+ apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) {
+ Progress progress(llvm::formatv("Loading Apple DWARF index for {0}",
+ module_desc.GetData()));
+ m_index = AppleDWARFIndex::Create(
+ *GetObjectFile()->GetModule(), apple_names, apple_namespaces,
+ apple_types, apple_objc, m_context.getOrLoadStrData());
- if (m_index)
- return;
+ if (m_index)
+ return;
+ }
DWARFDataExtractor debug_names;
LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
if (debug_names.GetByteSize() > 0) {
+ Progress progress(
+ llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData()));
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
debug_names,
@@ -669,9 +683,8 @@ static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu,
// files are NFS mounted.
file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
- std::string remapped_file;
- if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
- file_spec.SetFile(remapped_file, FileSpec::Style::native);
+ if (auto remapped_file = module_sp->RemapSourceFile(file_spec.GetPath()))
+ file_spec.SetFile(*remapped_file, FileSpec::Style::native);
}
lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
@@ -973,8 +986,7 @@ bool SymbolFileDWARF::ParseImportedModules(
if (!die)
return false;
- for (DWARFDIE child_die = die.GetFirstChild(); child_die;
- child_die = child_die.GetSibling()) {
+ for (DWARFDIE child_die : die.children()) {
if (child_die.Tag() != DW_TAG_imported_declaration)
continue;
@@ -1233,8 +1245,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
if (parent_die) {
- for (DWARFDIE die = parent_die.GetFirstChild(); die;
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
dw_tag_t tag = die.Tag();
bool check_virtuality = false;
switch (tag) {
@@ -1639,6 +1650,13 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
return nullptr;
dwo_file.SetFile(comp_dir, FileSpec::Style::native);
+ if (dwo_file.IsRelative()) {
+ // if DW_AT_comp_dir is relative, it should be relative to the location
+ // of the executable, not to the location from which the debugger was
+ // launched.
+ dwo_file.PrependPathComponent(
+ m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
+ }
FileSystem::Instance().Resolve(dwo_file);
dwo_file.AppendPathComponent(dwo_name);
}
@@ -1784,7 +1802,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr,
nullptr, location_result, &error)) {
if (location_result.GetValueType() ==
- Value::eValueTypeFileAddress) {
+ Value::ValueType::FileAddress) {
lldb::addr_t file_addr =
location_result.GetScalar().ULongLong();
lldb::addr_t byte_size = 1;
@@ -1850,17 +1868,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
DWARFDebugInfo &debug_info = DebugInfo();
- llvm::Expected<DWARFDebugAranges &> aranges =
- debug_info.GetCompileUnitAranges();
- if (!aranges) {
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- LLDB_LOG_ERROR(log, aranges.takeError(),
- "SymbolFileDWARF::ResolveSymbolContext failed to get cu "
- "aranges. {0}");
- return 0;
- }
-
- const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr);
+ const DWARFDebugAranges &aranges = debug_info.GetCompileUnitAranges();
+ const dw_offset_t cu_offset = aranges.FindAddress(file_vm_addr);
if (cu_offset == DW_INVALID_OFFSET) {
// Global variables are not in the compile unit address ranges. The only
// way to currently find global variables is to iterate over the
@@ -1949,12 +1958,11 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
return resolved;
}
-uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
- uint32_t line,
- bool check_inlines,
- SymbolContextItem resolve_scope,
- SymbolContextList &sc_list) {
+uint32_t SymbolFileDWARF::ResolveSymbolContext(
+ const SourceLocationSpec &src_location_spec,
+ SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ const bool check_inlines = src_location_spec.GetCheckInlines();
const uint32_t prev_size = sc_list.GetSize();
if (resolve_scope & eSymbolContextCompUnit) {
for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
@@ -1963,69 +1971,10 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
if (!dc_cu)
continue;
- bool file_spec_matches_cu_file_spec =
- FileSpec::Match(file_spec, dc_cu->GetPrimaryFile());
+ bool file_spec_matches_cu_file_spec = FileSpec::Match(
+ src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile());
if (check_inlines || file_spec_matches_cu_file_spec) {
- SymbolContext sc(m_objfile_sp->GetModule());
- sc.comp_unit = dc_cu;
- uint32_t file_idx = UINT32_MAX;
-
- // If we are looking for inline functions only and we don't find it
- // in the support files, we are done.
- if (check_inlines) {
- file_idx =
- sc.comp_unit->GetSupportFiles().FindFileIndex(1, file_spec, true);
- if (file_idx == UINT32_MAX)
- continue;
- }
-
- if (line != 0) {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table != nullptr && line != 0) {
- // We will have already looked up the file index if we are
- // searching for inline entries.
- if (!check_inlines)
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
- 1, file_spec, true);
-
- if (file_idx != UINT32_MAX) {
- uint32_t found_line;
- uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
- 0, file_idx, line, false, &sc.line_entry);
- found_line = sc.line_entry.line;
-
- while (line_idx != UINT32_MAX) {
- sc.function = nullptr;
- sc.block = nullptr;
- if (resolve_scope &
- (eSymbolContextFunction | eSymbolContextBlock)) {
- const lldb::addr_t file_vm_addr =
- sc.line_entry.range.GetBaseAddress().GetFileAddress();
- if (file_vm_addr != LLDB_INVALID_ADDRESS) {
- ResolveFunctionAndBlock(
- file_vm_addr, resolve_scope & eSymbolContextBlock, sc);
- }
- }
-
- sc_list.Append(sc);
- line_idx = line_table->FindLineEntryIndexByFileIndex(
- line_idx + 1, file_idx, found_line, true, &sc.line_entry);
- }
- }
- } else if (file_spec_matches_cu_file_spec && !check_inlines) {
- // only append the context if we aren't looking for inline call
- // sites by file and line and if the file spec matches that of
- // the compile unit
- sc_list.Append(sc);
- }
- } else if (file_spec_matches_cu_file_spec && !check_inlines) {
- // only append the context if we aren't looking for inline call
- // sites by file and line and if the file spec matches that of
- // the compile unit
- sc_list.Append(sc);
- }
-
+ dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
if (!check_inlines)
break;
}
@@ -2462,7 +2411,7 @@ void SymbolFileDWARF::FindTypes(
return;
m_index->GetTypes(name, [&](DWARFDIE die) {
- if (!languages[GetLanguage(*die.GetCU())])
+ if (!languages[GetLanguageFamily(*die.GetCU())])
return true;
llvm::SmallVector<CompilerContext, 4> die_context;
@@ -3126,8 +3075,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
continue;
switch (attr) {
case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
+ decl.SetFile(
+ attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));
break;
case DW_AT_decl_line:
decl.SetLine(form_value.Unsigned());
@@ -3469,8 +3418,7 @@ SymbolFileDWARF::FindBlockContainingSpecification(
// Give the concrete function die specified by "func_die_offset", find the
// concrete block whose DW_AT_specification or DW_AT_abstract_origin points
// to "spec_block_die_offset"
- for (DWARFDIE child_die = die.GetFirstChild(); child_die;
- child_die = child_die.GetSibling()) {
+ for (DWARFDIE child_die : die.children()) {
DWARFDIE result_die =
FindBlockContainingSpecification(child_die, spec_block_die_offset);
if (result_die)
@@ -3599,8 +3547,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
static CallSiteParameterArray
CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
CallSiteParameterArray parameters;
- for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid();
- child = child.GetSibling()) {
+ for (DWARFDIE child : call_site_die.children()) {
if (child.Tag() != DW_TAG_call_site_parameter &&
child.Tag() != DW_TAG_GNU_call_site_parameter)
continue;
@@ -3665,8 +3612,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
// For now, assume that all entries are nested directly under the subprogram
// (this is the kind of DWARF LLVM produces) and parse them eagerly.
std::vector<std::unique_ptr<CallEdge>> call_edges;
- for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid();
- child = child.GetSibling()) {
+ for (DWARFDIE child : function_die.children()) {
if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)
continue;
@@ -3842,7 +3788,7 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) {
}
SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
- if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) {
+ if (m_debug_map_symfile == nullptr) {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
if (module_sp) {
m_debug_map_symfile =
@@ -3936,3 +3882,10 @@ LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) {
LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) {
return LanguageTypeFromDWARF(unit.GetDWARFLanguageType());
}
+
+LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) {
+ auto lang = (llvm::dwarf::SourceLanguage)unit.GetDWARFLanguageType();
+ if (llvm::dwarf::isCPlusPlus(lang))
+ lang = DW_LANG_C_plus_plus;
+ return LanguageTypeFromDWARF(lang);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 019f76c67c63..d9feeef549ed 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -161,11 +161,10 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
- bool check_inlines,
- lldb::SymbolContextItem resolve_scope,
- lldb_private::SymbolContextList &sc_list) override;
+ uint32_t ResolveSymbolContext(
+ const lldb_private::SourceLocationSpec &src_location_spec,
+ lldb::SymbolContextItem resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
void
FindGlobalVariables(lldb_private::ConstString name,
@@ -318,6 +317,8 @@ public:
static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
static lldb::LanguageType GetLanguage(DWARFUnit &unit);
+ /// Same as GetLanguage() but reports all C++ versions as C++ (no version).
+ static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit);
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index fa24f975b073..4e2e5e16637b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -16,7 +16,6 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/RegularExpression.h"
-#include "lldb/Utility/Timer.h"
//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
#if defined(DEBUG_OSO_DMAP)
@@ -34,6 +33,9 @@
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
+// Work around the fact that Timer.h pulls in the system Mach-O headers.
+#include "lldb/Utility/Timer.h"
+
#include <memory>
using namespace lldb;
@@ -246,7 +248,7 @@ SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)
m_func_indexes(), m_glob_indexes(),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
-SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
+SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() = default;
void SymbolFileDWARFDebugMap::InitializeObject() {}
@@ -806,7 +808,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
}
uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
- const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ const SourceLocationSpec &src_location_spec,
SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint32_t initial = sc_list.GetSize();
@@ -815,18 +817,19 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
for (uint32_t i = 0; i < cu_count; ++i) {
// If we are checking for inlines, then we need to look through all compile
// units no matter if "file_spec" matches.
- bool resolve = check_inlines;
+ bool resolve = src_location_spec.GetCheckInlines();
if (!resolve) {
FileSpec so_file_spec;
if (GetFileSpecForSO(i, so_file_spec))
- resolve = FileSpec::Match(file_spec, so_file_spec);
+ resolve =
+ FileSpec::Match(src_location_spec.GetFileSpec(), so_file_spec);
}
if (resolve) {
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
if (oso_dwarf)
- oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines,
- resolve_scope, sc_list);
+ oso_dwarf->ResolveSymbolContext(src_location_spec, resolve_scope,
+ sc_list);
}
}
return sc_list.GetSize() - initial;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 06f0d48c04ca..8b6624e70869 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -97,11 +97,10 @@ public:
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
- bool check_inlines,
- lldb::SymbolContextItem resolve_scope,
- lldb_private::SymbolContextList &sc_list) override;
+ uint32_t ResolveSymbolContext(
+ const lldb_private::SourceLocationSpec &src_location_spec,
+ lldb::SymbolContextItem resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext &parent_decl_ctx,
@@ -171,18 +170,17 @@ protected:
llvm::sys::TimePoint<> oso_mod_time;
OSOInfoSP oso_sp;
lldb::CompUnitSP compile_unit_sp;
- uint32_t first_symbol_index;
- uint32_t last_symbol_index;
- uint32_t first_symbol_id;
- uint32_t last_symbol_id;
+ uint32_t first_symbol_index = UINT32_MAX;
+ uint32_t last_symbol_index = UINT32_MAX;
+ uint32_t first_symbol_id = UINT32_MAX;
+ uint32_t last_symbol_id = UINT32_MAX;
FileRangeMap file_range_map;
- bool file_range_map_valid;
+ bool file_range_map_valid = false;
CompileUnitInfo()
: so_file(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(),
- first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX),
- first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
- file_range_map(), file_range_map_valid(false) {}
+
+ file_range_map() {}
const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
};
@@ -280,8 +278,7 @@ protected:
// OSOEntry
class OSOEntry {
public:
- OSOEntry()
- : m_exe_sym_idx(UINT32_MAX), m_oso_file_addr(LLDB_INVALID_ADDRESS) {}
+ OSOEntry() = default;
OSOEntry(uint32_t exe_sym_idx, lldb::addr_t oso_file_addr)
: m_exe_sym_idx(exe_sym_idx), m_oso_file_addr(oso_file_addr) {}
@@ -299,8 +296,8 @@ protected:
}
protected:
- uint32_t m_exe_sym_idx;
- lldb::addr_t m_oso_file_addr;
+ uint32_t m_exe_sym_idx = UINT32_MAX;
+ lldb::addr_t m_oso_file_addr = LLDB_INVALID_ADDRESS;
};
typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry>
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 2181989cd37a..34ff23667465 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -8,7 +8,7 @@
#include "UniqueDWARFASTType.h"
-#include "lldb/Symbol/Declaration.h"
+#include "lldb/Core/Declaration.h"
bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
const lldb_private::Declaration &decl,
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index a1b1a3009787..0947d1e581c5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -14,16 +14,12 @@
#include "llvm/ADT/DenseMap.h"
#include "DWARFDIE.h"
-#include "lldb/Symbol/Declaration.h"
+#include "lldb/Core/Declaration.h"
class UniqueDWARFASTType {
public:
// Constructors and Destructors
- UniqueDWARFASTType()
- : m_type_sp(), m_die(), m_declaration(),
- m_byte_size(
- -1) // Set to negative value to make sure we have a valid value
- {}
+ UniqueDWARFASTType() : m_type_sp(), m_die(), m_declaration() {}
UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die,
const lldb_private::Declaration &decl, int32_t byte_size)
@@ -34,7 +30,7 @@ public:
: m_type_sp(rhs.m_type_sp), m_die(rhs.m_die),
m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {}
- ~UniqueDWARFASTType() {}
+ ~UniqueDWARFASTType() = default;
UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) {
if (this != &rhs) {
@@ -49,14 +45,14 @@ public:
lldb::TypeSP m_type_sp;
DWARFDIE m_die;
lldb_private::Declaration m_declaration;
- int32_t m_byte_size;
+ int32_t m_byte_size = -1;
};
class UniqueDWARFASTTypeList {
public:
UniqueDWARFASTTypeList() : m_collection() {}
- ~UniqueDWARFASTTypeList() {}
+ ~UniqueDWARFASTTypeList() = default;
uint32_t GetSize() { return (uint32_t)m_collection.size(); }
@@ -76,7 +72,7 @@ class UniqueDWARFASTTypeMap {
public:
UniqueDWARFASTTypeMap() : m_collection() {}
- ~UniqueDWARFASTTypeMap() {}
+ ~UniqueDWARFASTTypeMap() = default;
void Insert(lldb_private::ConstString name,
const UniqueDWARFASTType &entry) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index f25dc84fb342..9f09c0accc87 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -43,7 +43,7 @@ static bool IsMainFile(llvm::StringRef main, llvm::StringRef other) {
llvm::SmallString<64> normalized(other);
llvm::sys::path::native(normalized);
- return main.equals_lower(normalized);
+ return main.equals_insensitive(normalized);
}
static void ParseCompile3(const CVSymbol &sym, CompilandIndexItem &cci) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 5b4ab78ac219..43cf262016c2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1093,7 +1093,7 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
}
if (!params.empty())
- m_clang.SetFunctionParameters(&function_decl, params.data(), params.size());
+ m_clang.SetFunctionParameters(&function_decl, params);
}
clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
index ecae767e4469..4f570d5e6788 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -41,7 +41,7 @@ static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::A
auto it = llvm::find_if(
register_names,
[&reg_name](const llvm::EnumEntry<uint16_t> &register_entry) {
- return reg_name.compare_lower(register_entry.Name) == 0;
+ return reg_name.compare_insensitive(register_entry.Name) == 0;
});
if (it == register_names.end())
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 24b4c64a91bc..b9b075d83b6a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -256,7 +256,7 @@ SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
: SymbolFile(std::move(objfile_sp)) {}
-SymbolFileNativePDB::~SymbolFileNativePDB() {}
+SymbolFileNativePDB::~SymbolFileNativePDB() = default;
uint32_t SymbolFileNativePDB::CalculateAbilities() {
uint32_t abilities = 0;
@@ -1001,7 +1001,7 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext(
}
uint32_t SymbolFileNativePDB::ResolveSymbolContext(
- const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ const SourceLocationSpec &src_location_spec,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
return 0;
}
@@ -1039,7 +1039,7 @@ static void TerminateLineSequence(LineTable &table,
table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize,
last_line, 0, file_number, false, false,
false, false, true);
- table.InsertSequence(seq.release());
+ table.InsertSequence(seq.get());
}
bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 61c1d77164b7..def0995065ca 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -120,8 +120,7 @@ public:
uint32_t ResolveSymbolContext(const Address &so_addr,
lldb::SymbolContextItem resolve_scope,
SymbolContext &sc) override;
- uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line,
- bool check_inlines,
+ uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index f9c12e634140..78a0d09a681a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -17,8 +17,8 @@
#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/Core/Declaration.h"
#include "lldb/Core/Module.h"
-#include "lldb/Symbol/Declaration.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
@@ -326,7 +326,7 @@ GetDeclFromContextByName(const clang::ASTContext &ast,
if (result.empty())
return nullptr;
- return result[0];
+ return *result.begin();
}
static bool IsAnonymousNamespaceName(llvm::StringRef name) {
@@ -355,7 +355,7 @@ static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {
PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {}
-PDBASTParser::~PDBASTParser() {}
+PDBASTParser::~PDBASTParser() = default;
// DebugInfoASTParser interface
@@ -534,8 +534,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
assert(type_def);
+ SymbolFile *symbol_file = m_ast.GetSymbolFile();
+ if (!symbol_file)
+ return nullptr;
+
lldb_private::Type *target_type =
- m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
+ symbol_file->ResolveTypeUID(type_def->getTypeId());
if (!target_type)
return nullptr;
@@ -609,8 +613,13 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
auto arg = arg_enum->getChildAtIndex(arg_idx);
if (!arg)
break;
+
+ SymbolFile *symbol_file = m_ast.GetSymbolFile();
+ if (!symbol_file)
+ return nullptr;
+
lldb_private::Type *arg_type =
- m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
+ symbol_file->ResolveTypeUID(arg->getSymIndexId());
// If there's some error looking up one of the dependent types of this
// function signature, bail.
if (!arg_type)
@@ -621,8 +630,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
lldbassert(arg_list.size() <= num_args);
auto pdb_return_type = func_sig->getReturnType();
+ SymbolFile *symbol_file = m_ast.GetSymbolFile();
+ if (!symbol_file)
+ return nullptr;
+
lldb_private::Type *return_type =
- m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
+ symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId());
// If there's some error looking up one of the dependent types of this
// function signature, bail.
if (!return_type)
@@ -654,10 +667,13 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
if (uint64_t size = array_type->getLength())
bytes = size;
+ SymbolFile *symbol_file = m_ast.GetSymbolFile();
+ if (!symbol_file)
+ return nullptr;
+
// If array rank > 0, PDB gives the element type at N=0. So element type
// will parsed in the order N=0, N=1,..., N=rank sequentially.
- lldb_private::Type *element_type =
- m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+ lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid);
if (!element_type)
return nullptr;
@@ -711,7 +727,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
case PDB_SymType::PointerType: {
auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
assert(pointer_type);
- Type *pointee_type = m_ast.GetSymbolFile()->ResolveTypeUID(
+
+ SymbolFile *symbol_file = m_ast.GetSymbolFile();
+ if (!symbol_file)
+ return nullptr;
+
+ Type *pointee_type = symbol_file->ResolveTypeUID(
pointer_type->getPointeeType()->getSymIndexId());
if (!pointee_type)
return nullptr;
@@ -719,8 +740,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
if (pointer_type->isPointerToDataMember() ||
pointer_type->isPointerToMemberFunction()) {
auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId();
- auto class_parent_type =
- m_ast.GetSymbolFile()->ResolveTypeUID(class_parent_uid);
+ auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid);
assert(class_parent_type);
CompilerType pointer_ast_type;
@@ -950,7 +970,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
}
}
if (params.size())
- m_ast.SetFunctionParameters(decl, params.data(), params.size());
+ m_ast.SetFunctionParameters(decl, params);
m_uid_to_decl[sym_id] = decl;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index befc08158cea..6b30ad26dca7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -84,8 +84,10 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
static bool ShouldUseNativeReader() {
#if defined(_WIN32)
llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER");
- return use_native.equals_lower("on") || use_native.equals_lower("yes") ||
- use_native.equals_lower("1") || use_native.equals_lower("true");
+ return use_native.equals_insensitive("on") ||
+ use_native.equals_insensitive("yes") ||
+ use_native.equals_insensitive("1") ||
+ use_native.equals_insensitive("true");
#else
return true;
#endif
@@ -128,7 +130,7 @@ SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) {
SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp)
: SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {}
-SymbolFilePDB::~SymbolFilePDB() {}
+SymbolFilePDB::~SymbolFilePDB() = default;
uint32_t SymbolFilePDB::CalculateAbilities() {
uint32_t abilities = 0;
@@ -784,10 +786,12 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
}
uint32_t SymbolFilePDB::ResolveSymbolContext(
- const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
+ const lldb_private::SourceLocationSpec &src_location_spec,
SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const size_t old_size = sc_list.GetSize();
+ const FileSpec &file_spec = src_location_spec.GetFileSpec();
+ const uint32_t line = src_location_spec.GetLine().getValueOr(0);
if (resolve_scope & lldb::eSymbolContextCompUnit) {
// Locate all compilation units with line numbers referencing the specified
// file. For example, if `file_spec` is <vector>, then this should return
@@ -806,7 +810,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(
// this file unless the FileSpec matches. For inline functions, we don't
// have to match the FileSpec since they could be defined in headers
// other than file specified in FileSpec.
- if (!check_inlines) {
+ if (!src_location_spec.GetCheckInlines()) {
std::string source_file = compiland->getSourceFileFullPath();
if (source_file.empty())
continue;
@@ -1813,7 +1817,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
sequence.get(), prev_addr + prev_length, prev_line, 0,
prev_source_idx, false, false, false, false, true);
- line_table->InsertSequence(sequence.release());
+ line_table->InsertSequence(sequence.get());
sequence = line_table->CreateLineSequenceContainer();
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 928cbffc5f63..2171b7f686cc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -104,11 +104,10 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
- bool check_inlines,
- lldb::SymbolContextItem resolve_scope,
- lldb_private::SymbolContextList &sc_list) override;
+ uint32_t ResolveSymbolContext(
+ const lldb_private::SourceLocationSpec &src_location_spec,
+ lldb::SymbolContextItem resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
void
FindGlobalVariables(lldb_private::ConstString name,
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index 4df5140bd7e1..9130eed63e43 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -8,7 +8,7 @@
#include "SymbolVendorELF.h"
-#include <string.h>
+#include <cstring>
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "lldb/Core/Module.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
index 67a1ef5e4e51..2b2840796579 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
@@ -8,7 +8,7 @@
#include "SymbolVendorWasm.h"
-#include <string.h>
+#include <cstring>
#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
#include "lldb/Core/Module.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp
new file mode 100644
index 000000000000..45d6f3b0e098
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp
@@ -0,0 +1,41 @@
+//===-- ThreadPostMortemTrace.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ThreadPostMortemTrace.h"
+
+#include <memory>
+
+#include "Plugins/Process/Utility/RegisterContextHistory.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void ThreadPostMortemTrace::RefreshStateAfterStop() {}
+
+RegisterContextSP ThreadPostMortemTrace::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+
+ return m_reg_context_sp;
+}
+
+RegisterContextSP
+ThreadPostMortemTrace::CreateRegisterContextForFrame(StackFrame *frame) {
+ // Eventually this will calculate the register context based on the current
+ // trace position.
+ return std::make_shared<RegisterContextHistory>(
+ *this, 0, GetProcess()->GetAddressByteSize(), LLDB_INVALID_ADDRESS);
+}
+
+bool ThreadPostMortemTrace::CalculateStopInfo() { return false; }
+
+const FileSpec &ThreadPostMortemTrace::GetTraceFile() const {
+ return m_trace_file;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h
new file mode 100644
index 000000000000..9cfe754ae0e4
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h
@@ -0,0 +1,60 @@
+//===-- ThreadPostMortemTrace.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_THREADPOSTMORTEMTRACE_H
+#define LLDB_TARGET_THREADPOSTMORTEMTRACE_H
+
+#include "lldb/Target/Thread.h"
+
+namespace lldb_private {
+
+/// \class ThreadPostMortemTrace ThreadPostMortemTrace.h
+///
+/// Thread implementation used for representing threads gotten from trace
+/// session files, which are similar to threads from core files.
+///
+/// See \a TraceSessionFileParser for more information regarding trace session
+/// files.
+class ThreadPostMortemTrace : public Thread {
+public:
+ /// \param[in] process
+ /// The process who owns this thread.
+ ///
+ /// \param[in] tid
+ /// The tid of this thread.
+ ///
+ /// \param[in] trace_file
+ /// The file that contains the list of instructions that were traced when
+ /// this thread was being executed.
+ ThreadPostMortemTrace(Process &process, lldb::tid_t tid,
+ const FileSpec &trace_file)
+ : Thread(process, tid), m_trace_file(trace_file) {}
+
+ void RefreshStateAfterStop() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+
+ /// \return
+ /// The trace file of this thread.
+ const FileSpec &GetTraceFile() const;
+
+protected:
+ bool CalculateStopInfo() override;
+
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+
+private:
+ FileSpec m_trace_file;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_THREADPOSTMORTEMTRACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
new file mode 100644
index 000000000000..c88ad9dc6a59
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
@@ -0,0 +1,224 @@
+//===-- TraceSessionFileParser.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===/
+
+#include "TraceSessionFileParser.h"
+#include "ThreadPostMortemTrace.h"
+
+#include <sstream>
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+void TraceSessionFileParser::NormalizePath(lldb_private::FileSpec &file_spec) {
+ if (file_spec.IsRelative())
+ file_spec.PrependPathComponent(m_session_file_dir);
+}
+
+Error TraceSessionFileParser::ParseModule(lldb::TargetSP &target_sp,
+ const JSONModule &module) {
+ FileSpec system_file_spec(module.system_path);
+ NormalizePath(system_file_spec);
+
+ FileSpec local_file_spec(module.file.hasValue() ? *module.file
+ : module.system_path);
+ NormalizePath(local_file_spec);
+
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec() = local_file_spec;
+ module_spec.GetPlatformFileSpec() = system_file_spec;
+
+ if (module.uuid.hasValue())
+ module_spec.GetUUID().SetFromStringRef(*module.uuid);
+
+ Status error;
+ ModuleSP module_sp =
+ target_sp->GetOrCreateModule(module_spec, /*notify*/ false, &error);
+
+ if (error.Fail())
+ return error.ToError();
+
+ bool load_addr_changed = false;
+ module_sp->SetLoadAddress(*target_sp, module.load_address.value, false,
+ load_addr_changed);
+ return llvm::Error::success();
+}
+
+Error TraceSessionFileParser::CreateJSONError(json::Path::Root &root,
+ const json::Value &value) {
+ std::string err;
+ raw_string_ostream os(err);
+ root.printErrorContext(value, os);
+ return createStringError(
+ std::errc::invalid_argument, "%s\n\nContext:\n%s\n\nSchema:\n%s",
+ toString(root.getError()).c_str(), os.str().c_str(), m_schema.data());
+}
+
+std::string TraceSessionFileParser::BuildSchema(StringRef plugin_schema) {
+ std::ostringstream schema_builder;
+ schema_builder << "{\n \"trace\": ";
+ schema_builder << plugin_schema.data() << ",";
+ schema_builder << R"(
+ "processes": [
+ {
+ "pid": integer,
+ "triple": string, // llvm-triple
+ "threads": [
+ {
+ "tid": integer,
+ "traceFile": string
+ }
+ ],
+ "modules": [
+ {
+ "systemPath": string, // original path of the module at runtime
+ "file"?: string, // copy of the file if not available at "systemPath"
+ "loadAddress": string, // string address in hex or decimal form
+ "uuid"?: string,
+ }
+ ]
+ }
+ ]
+ // Notes:
+ // All paths are either absolute or relative to the session file.
+}
+)";
+ return schema_builder.str();
+}
+
+ThreadPostMortemTraceSP
+TraceSessionFileParser::ParseThread(ProcessSP &process_sp,
+ const JSONThread &thread) {
+ lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid);
+
+ FileSpec trace_file(thread.trace_file);
+ NormalizePath(trace_file);
+
+ ThreadPostMortemTraceSP thread_sp =
+ std::make_shared<ThreadPostMortemTrace>(*process_sp, tid, trace_file);
+ process_sp->GetThreadList().AddThread(thread_sp);
+ return thread_sp;
+}
+
+Expected<TraceSessionFileParser::ParsedProcess>
+TraceSessionFileParser::ParseProcess(const JSONProcess &process) {
+ TargetSP target_sp;
+ Status error = m_debugger.GetTargetList().CreateTarget(
+ m_debugger, /*user_exe_path*/ StringRef(), process.triple,
+ eLoadDependentsNo,
+ /*platform_options*/ nullptr, target_sp);
+
+ if (!target_sp)
+ return error.ToError();
+
+ ParsedProcess parsed_process;
+ parsed_process.target_sp = target_sp;
+
+ ProcessSP process_sp = target_sp->CreateProcess(
+ /*listener*/ nullptr, "trace",
+ /*crash_file*/ nullptr,
+ /*can_connect*/ false);
+
+ process_sp->SetID(static_cast<lldb::pid_t>(process.pid));
+
+ for (const JSONThread &thread : process.threads)
+ parsed_process.threads.push_back(ParseThread(process_sp, thread));
+
+ for (const JSONModule &module : process.modules)
+ if (Error err = ParseModule(target_sp, module))
+ return std::move(err);
+
+ if (!process.threads.empty())
+ process_sp->GetThreadList().SetSelectedThreadByIndexID(0);
+
+ // We invoke DidAttach to create a correct stopped state for the process and
+ // its threads.
+ ArchSpec process_arch;
+ process_sp->DidAttach(process_arch);
+
+ return parsed_process;
+}
+
+Expected<std::vector<TraceSessionFileParser::ParsedProcess>>
+TraceSessionFileParser::ParseCommonSessionFile(
+ const JSONTraceSessionBase &session) {
+ std::vector<ParsedProcess> parsed_processes;
+
+ auto onError = [&]() {
+ // Delete all targets that were created so far in case of failures
+ for (ParsedProcess &parsed_process : parsed_processes)
+ m_debugger.GetTargetList().DeleteTarget(parsed_process.target_sp);
+ };
+
+ for (const JSONProcess &process : session.processes) {
+ if (Expected<ParsedProcess> parsed_process = ParseProcess(process))
+ parsed_processes.push_back(std::move(*parsed_process));
+ else {
+ onError();
+ return parsed_process.takeError();
+ }
+ }
+ return parsed_processes;
+}
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONAddress &address,
+ Path path) {
+ Optional<StringRef> s = value.getAsString();
+ if (s.hasValue() && !s->getAsInteger(0, address.value))
+ return true;
+
+ path.report("expected numeric string");
+ return false;
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONModule &module,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("systemPath", module.system_path) &&
+ o.map("file", module.file) &&
+ o.map("loadAddress", module.load_address) &&
+ o.map("uuid", module.uuid);
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONThread &thread,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("tid", thread.tid) && o.map("traceFile", thread.trace_file);
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONProcess &process,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&
+ o.map("threads", process.threads) && o.map("modules", process.modules);
+}
+
+bool fromJSON(const Value &value,
+ TraceSessionFileParser::JSONTracePluginSettings &plugin_settings,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("type", plugin_settings.type);
+}
+
+bool fromJSON(const Value &value,
+ TraceSessionFileParser::JSONTraceSessionBase &session,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("processes", session.processes);
+}
+
+} // namespace json
+} // namespace llvm
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
new file mode 100644
index 000000000000..6abaffcecd3a
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
@@ -0,0 +1,179 @@
+//===-- TraceSessionFileParser.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_TRACESESSIONPARSER_H
+#define LLDB_TARGET_TRACESESSIONPARSER_H
+
+#include "llvm/Support/JSON.h"
+
+#include "ThreadPostMortemTrace.h"
+
+namespace lldb_private {
+
+/// \class TraceSessionFileParser TraceSessionFileParser.h
+///
+/// Base class for parsing the common information of JSON trace session files.
+/// Contains the basic C++ structs that represent the JSON data, which include
+/// \a JSONTraceSession as the root object.
+///
+/// See \a Trace::FindPlugin for more information regarding these JSON files.
+class TraceSessionFileParser {
+public:
+ /// C++ structs representing the JSON trace session.
+ /// \{
+ struct JSONAddress {
+ lldb::addr_t value;
+ };
+
+ struct JSONModule {
+ std::string system_path;
+ llvm::Optional<std::string> file;
+ JSONAddress load_address;
+ llvm::Optional<std::string> uuid;
+ };
+
+ struct JSONThread {
+ int64_t tid;
+ std::string trace_file;
+ };
+
+ struct JSONProcess {
+ int64_t pid;
+ std::string triple;
+ std::vector<JSONThread> threads;
+ std::vector<JSONModule> modules;
+ };
+
+ struct JSONTracePluginSettings {
+ std::string type;
+ };
+
+ struct JSONTraceSessionBase {
+ std::vector<JSONProcess> processes;
+ };
+
+ /// The trace plug-in implementation should provide its own TPluginSettings,
+ /// which corresponds to the "trace" section of the schema.
+ template <class TPluginSettings>
+ struct JSONTraceSession : JSONTraceSessionBase {
+ TPluginSettings trace;
+ };
+ /// \}
+
+ /// Helper struct holding the objects created when parsing a process
+ struct ParsedProcess {
+ lldb::TargetSP target_sp;
+ std::vector<lldb::ThreadPostMortemTraceSP> threads;
+ };
+
+ TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir,
+ llvm::StringRef schema)
+ : m_debugger(debugger), m_session_file_dir(session_file_dir),
+ m_schema(schema) {}
+
+ /// Build the full schema for a Trace plug-in.
+ ///
+ /// \param[in] plugin_schema
+ /// The subschema that corresponds to the "trace" section of the schema.
+ ///
+ /// \return
+ /// The full schema containing the common attributes and the plug-in
+ /// specific attributes.
+ static std::string BuildSchema(llvm::StringRef plugin_schema);
+
+ /// Parse the fields common to all trace session schemas.
+ ///
+ /// \param[in] session
+ /// The session json objects already deserialized.
+ ///
+ /// \return
+ /// A list of \a ParsedProcess containing all threads and targets created
+ /// during the parsing, or an error in case of failures. In case of
+ /// errors, no side effects are produced.
+ llvm::Expected<std::vector<ParsedProcess>>
+ ParseCommonSessionFile(const JSONTraceSessionBase &session);
+
+protected:
+ /// Resolve non-absolute paths relative to the session file folder. It
+ /// modifies the given file_spec.
+ void NormalizePath(lldb_private::FileSpec &file_spec);
+
+ lldb::ThreadPostMortemTraceSP ParseThread(lldb::ProcessSP &process_sp,
+ const JSONThread &thread);
+
+ llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process);
+
+ llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module);
+
+ /// Create a user-friendly error message upon a JSON-parsing failure using the
+ /// \a json::ObjectMapper functionality.
+ ///
+ /// \param[in] root
+ /// The \a llvm::json::Path::Root used to parse the JSON \a value.
+ ///
+ /// \param[in] value
+ /// The json value that failed to parse.
+ ///
+ /// \return
+ /// An \a llvm::Error containing the user-friendly error message.
+ llvm::Error CreateJSONError(llvm::json::Path::Root &root,
+ const llvm::json::Value &value);
+
+ Debugger &m_debugger;
+ std::string m_session_file_dir;
+ llvm::StringRef m_schema;
+};
+} // namespace lldb_private
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONAddress &address,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONModule &module,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONThread &thread,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONProcess &process,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONTracePluginSettings
+ &plugin_settings,
+ Path path);
+
+bool fromJSON(
+ const Value &value,
+ lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session,
+ Path path);
+
+template <class TPluginSettings>
+bool fromJSON(
+ const Value &value,
+ lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings>
+ &session,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("trace", session.trace) &&
+ fromJSON(value,
+ (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &)
+ session,
+ path);
+}
+
+} // namespace json
+} // namespace llvm
+
+#endif // LLDB_TARGET_TRACESESSIONPARSER_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
index e1758dfcfc41..5650af657c5e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
@@ -8,7 +8,10 @@
#include "CommandObjectTraceStartIntelPT.h"
+#include "TraceIntelPT.h"
+#include "TraceIntelPTConstants.h"
#include "lldb/Host/OptionParser.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Trace.h"
using namespace lldb;
@@ -16,10 +19,12 @@ using namespace lldb_private;
using namespace lldb_private::trace_intel_pt;
using namespace llvm;
+// CommandObjectThreadTraceStartIntelPT
+
#define LLDB_OPTIONS_thread_trace_start_intel_pt
#include "TraceIntelPTCommandOptions.inc"
-Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue(
+Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue(
uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) {
Status error;
@@ -27,23 +32,27 @@ Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue(
switch (short_option) {
case 's': {
- int32_t size_in_kb;
- if (option_arg.empty() || option_arg.getAsInteger(0, size_in_kb) ||
- size_in_kb < 0)
+ int64_t thread_buffer_size;
+ if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) ||
+ thread_buffer_size < 0)
error.SetErrorStringWithFormat("invalid integer value for option '%s'",
option_arg.str().c_str());
else
- m_size_in_kb = size_in_kb;
+ m_thread_buffer_size = thread_buffer_size;
+ break;
+ }
+ case 't': {
+ m_enable_tsc = true;
break;
}
- case 'c': {
- int32_t custom_config;
- if (option_arg.empty() || option_arg.getAsInteger(0, custom_config) ||
- custom_config < 0)
+ case 'p': {
+ int64_t psb_period;
+ if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) ||
+ psb_period < 0)
error.SetErrorStringWithFormat("invalid integer value for option '%s'",
option_arg.str().c_str());
else
- m_custom_config = custom_config;
+ m_psb_period = psb_period;
break;
}
default:
@@ -52,22 +61,104 @@ Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue(
return error;
}
-void CommandObjectTraceStartIntelPT::CommandOptions::OptionParsingStarting(
- ExecutionContext *execution_context) {
- m_size_in_kb = 4;
- m_custom_config = 0;
+void CommandObjectThreadTraceStartIntelPT::CommandOptions::
+ OptionParsingStarting(ExecutionContext *execution_context) {
+ m_thread_buffer_size = kDefaultThreadBufferSize;
+ m_enable_tsc = kDefaultEnableTscValue;
+ m_psb_period = kDefaultPsbPeriod;
}
llvm::ArrayRef<OptionDefinition>
-CommandObjectTraceStartIntelPT::CommandOptions::GetDefinitions() {
+CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() {
return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options);
}
-bool CommandObjectTraceStartIntelPT::HandleOneThread(
- lldb::tid_t tid, CommandReturnObject &result) {
- result.AppendMessageWithFormat(
- "would trace tid %" PRIu64 " with size_in_kb %zu and custom_config %d\n",
- tid, m_options.m_size_in_kb, m_options.m_custom_config);
- result.SetStatus(eReturnStatusSuccessFinishResult);
+bool CommandObjectThreadTraceStartIntelPT::DoExecuteOnThreads(
+ Args &command, CommandReturnObject &result,
+ llvm::ArrayRef<lldb::tid_t> tids) {
+ if (Error err = m_trace.Start(tids, m_options.m_thread_buffer_size,
+ m_options.m_enable_tsc, m_options.m_psb_period))
+ result.SetError(Status(std::move(err)));
+ else
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ return result.Succeeded();
+}
+
+/// CommandObjectProcessTraceStartIntelPT
+
+#define LLDB_OPTIONS_process_trace_start_intel_pt
+#include "TraceIntelPTCommandOptions.inc"
+
+Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 's': {
+ int64_t thread_buffer_size;
+ if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) ||
+ thread_buffer_size < 0)
+ error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_thread_buffer_size = thread_buffer_size;
+ break;
+ }
+ case 'l': {
+ int64_t process_buffer_size_limit;
+ if (option_arg.empty() ||
+ option_arg.getAsInteger(0, process_buffer_size_limit) ||
+ process_buffer_size_limit < 0)
+ error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_process_buffer_size_limit = process_buffer_size_limit;
+ break;
+ }
+ case 't': {
+ m_enable_tsc = true;
+ break;
+ }
+ case 'p': {
+ int64_t psb_period;
+ if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) ||
+ psb_period < 0)
+ error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_psb_period = psb_period;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+}
+
+void CommandObjectProcessTraceStartIntelPT::CommandOptions::
+ OptionParsingStarting(ExecutionContext *execution_context) {
+ m_thread_buffer_size = kDefaultThreadBufferSize;
+ m_process_buffer_size_limit = kDefaultProcessBufferSizeLimit;
+ m_enable_tsc = kDefaultEnableTscValue;
+ m_psb_period = kDefaultPsbPeriod;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_process_trace_start_intel_pt_options);
+}
+
+bool CommandObjectProcessTraceStartIntelPT::DoExecute(
+ Args &command, CommandReturnObject &result) {
+ if (Error err = m_trace.Start(m_options.m_thread_buffer_size,
+ m_options.m_process_buffer_size_limit,
+ m_options.m_enable_tsc, m_options.m_psb_period))
+ result.SetError(Status(std::move(err)));
+ else
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
return result.Succeeded();
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
index 265569c553fa..2f3d53a86406 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
@@ -9,21 +9,21 @@
#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H
#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H
-#include "../../../../source/Commands/CommandObjectThreadUtil.h"
+#include "../../../../source/Commands/CommandObjectTrace.h"
+#include "TraceIntelPT.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
namespace lldb_private {
namespace trace_intel_pt {
-class CommandObjectTraceStartIntelPT : public CommandObjectIterateOverThreads {
+class CommandObjectThreadTraceStartIntelPT
+ : public CommandObjectMultipleThreads {
public:
class CommandOptions : public Options {
public:
CommandOptions() : Options() { OptionParsingStarting(nullptr); }
- ~CommandOptions() override = default;
-
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) override;
@@ -31,31 +31,76 @@ public:
llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
- size_t m_size_in_kb;
- uint32_t m_custom_config;
+ size_t m_thread_buffer_size;
+ bool m_enable_tsc;
+ llvm::Optional<size_t> m_psb_period;
};
- CommandObjectTraceStartIntelPT(CommandInterpreter &interpreter)
- : CommandObjectIterateOverThreads(
+ CommandObjectThreadTraceStartIntelPT(TraceIntelPT &trace,
+ CommandInterpreter &interpreter)
+ : CommandObjectMultipleThreads(
interpreter, "thread trace start",
"Start tracing one or more threads with intel-pt. "
"Defaults to the current thread. Thread indices can be "
"specified as arguments.\n Use the thread-index \"all\" to trace "
- "all threads.",
+ "all threads including future threads.",
"thread trace start [<thread-index> <thread-index> ...] "
"[<intel-pt-options>]",
lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
lldb::eCommandProcessMustBeLaunched |
lldb::eCommandProcessMustBePaused),
- m_options() {}
+ m_trace(trace), m_options() {}
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
+ llvm::ArrayRef<lldb::tid_t> tids) override;
+
+ TraceIntelPT &m_trace;
+ CommandOptions m_options;
+};
+
+class CommandObjectProcessTraceStartIntelPT : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
- ~CommandObjectTraceStartIntelPT() override = default;
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ size_t m_thread_buffer_size;
+ size_t m_process_buffer_size_limit;
+ bool m_enable_tsc;
+ llvm::Optional<size_t> m_psb_period;
+ };
+
+ CommandObjectProcessTraceStartIntelPT(TraceIntelPT &trace,
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "process trace start",
+ "Start tracing this process with intel-pt, including future "
+ "threads. "
+ "This is implemented by tracing each thread independently. "
+ "Threads traced with the \"thread trace start\" command are left "
+ "unaffected ant not retraced.",
+ "process trace start [<intel-pt-options>]",
+ lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
+ lldb::eCommandProcessMustBeLaunched |
+ lldb::eCommandProcessMustBePaused),
+ m_trace(trace), m_options() {}
Options *GetOptions() override { return &m_options; }
protected:
- bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override;
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
+ TraceIntelPT &m_trace;
CommandOptions m_options;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
index 6b8b06564052..4822a786c68c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
@@ -8,8 +8,13 @@
#include "DecodedThread.h"
+#include <intel-pt.h>
+#include <memory>
+
+#include "TraceCursorIntelPT.h"
#include "lldb/Utility/StreamString.h"
+using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::trace_intel_pt;
using namespace llvm;
@@ -30,12 +35,21 @@ void IntelPTError::log(llvm::raw_ostream &OS) const {
OS << "error: " << libipt_error_message;
}
+IntelPTInstruction::IntelPTInstruction(llvm::Error err) {
+ llvm::handleAllErrors(std::move(err),
+ [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
+ m_error = std::move(info);
+ });
+ m_pt_insn.ip = LLDB_INVALID_ADDRESS;
+ m_pt_insn.iclass = ptic_error;
+}
+
bool IntelPTInstruction::IsError() const { return (bool)m_error; }
-Expected<lldb::addr_t> IntelPTInstruction::GetLoadAddress() const {
- if (IsError())
- return ToError();
- return m_pt_insn.ip;
+lldb::addr_t IntelPTInstruction::GetLoadAddress() const { return m_pt_insn.ip; }
+
+Optional<uint64_t> IntelPTInstruction::GetTimestampCounter() const {
+ return m_timestamp;
}
Error IntelPTInstruction::ToError() const {
@@ -47,18 +61,58 @@ Error IntelPTInstruction::ToError() const {
return make_error<StringError>(m_error->message(),
m_error->convertToErrorCode());
}
+size_t DecodedThread::GetRawTraceSize() const { return m_raw_trace_size; }
+
+TraceInstructionControlFlowType
+IntelPTInstruction::GetControlFlowType(lldb::addr_t next_load_address) const {
+ if (IsError())
+ return (TraceInstructionControlFlowType)0;
-size_t DecodedThread::GetLastPosition() const {
- return m_instructions.empty() ? 0 : m_instructions.size() - 1;
+ TraceInstructionControlFlowType mask =
+ eTraceInstructionControlFlowTypeInstruction;
+
+ switch (m_pt_insn.iclass) {
+ case ptic_cond_jump:
+ case ptic_jump:
+ case ptic_far_jump:
+ mask |= eTraceInstructionControlFlowTypeBranch;
+ if (m_pt_insn.ip + m_pt_insn.size != next_load_address)
+ mask |= eTraceInstructionControlFlowTypeTakenBranch;
+ break;
+ case ptic_return:
+ case ptic_far_return:
+ mask |= eTraceInstructionControlFlowTypeReturn;
+ break;
+ case ptic_call:
+ case ptic_far_call:
+ mask |= eTraceInstructionControlFlowTypeCall;
+ break;
+ default:
+ break;
+ }
+
+ return mask;
}
ArrayRef<IntelPTInstruction> DecodedThread::GetInstructions() const {
return makeArrayRef(m_instructions);
}
-size_t DecodedThread::GetCursorPosition() const { return m_position; }
+DecodedThread::DecodedThread(ThreadSP thread_sp, Error error)
+ : m_thread_sp(thread_sp) {
+ m_instructions.emplace_back(std::move(error));
+}
+
+DecodedThread::DecodedThread(ThreadSP thread_sp,
+ std::vector<IntelPTInstruction> &&instructions,
+ size_t raw_trace_size)
+ : m_thread_sp(thread_sp), m_instructions(std::move(instructions)),
+ m_raw_trace_size(raw_trace_size) {
+ if (m_instructions.empty())
+ m_instructions.emplace_back(
+ createStringError(inconvertibleErrorCode(), "empty trace"));
+}
-size_t DecodedThread::SetCursorPosition(size_t new_position) {
- m_position = std::min(new_position, GetLastPosition());
- return m_position;
+lldb::TraceCursorUP DecodedThread::GetCursor() {
+ return std::make_unique<TraceCursorIntelPT>(m_thread_sp, shared_from_this());
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
index 3c7e030414cb..592c402cd0e5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
@@ -15,6 +15,7 @@
#include "llvm/Support/Error.h"
#include "lldb/Target/Trace.h"
+#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
#include "intel-pt.h"
@@ -60,17 +61,15 @@ private:
/// As mentioned, any gap is represented as an error in this class.
class IntelPTInstruction {
public:
+ IntelPTInstruction(const pt_insn &pt_insn, uint64_t timestamp)
+ : m_pt_insn(pt_insn), m_timestamp(timestamp) {}
+
IntelPTInstruction(const pt_insn &pt_insn) : m_pt_insn(pt_insn) {}
/// Error constructor
///
/// libipt errors should use the underlying \a IntelPTError class.
- IntelPTInstruction(llvm::Error err) {
- llvm::handleAllErrors(std::move(err),
- [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
- m_error = std::move(info);
- });
- }
+ IntelPTInstruction(llvm::Error err);
/// Check if this object represents an error (i.e. a gap).
///
@@ -79,15 +78,34 @@ public:
bool IsError() const;
/// \return
- /// The instruction pointer address, or an \a llvm::Error if it is an
- /// error.
- llvm::Expected<lldb::addr_t> GetLoadAddress() const;
+ /// The instruction pointer address, or \a LLDB_INVALID_ADDRESS if it is
+ /// an error.
+ lldb::addr_t GetLoadAddress() const;
/// \return
/// An \a llvm::Error object if this class corresponds to an Error, or an
/// \a llvm::Error::success otherwise.
llvm::Error ToError() const;
+ /// Get the timestamp associated with the current instruction. The timestamp
+ /// is similar to what a rdtsc instruction would return.
+ ///
+ /// \return
+ /// The timestamp or \b llvm::None if not available.
+ llvm::Optional<uint64_t> GetTimestampCounter() const;
+
+ /// Get the \a lldb::TraceInstructionControlFlowType categories of the
+ /// instruction.
+ ///
+ /// \param[in] next_load_address
+ /// The address of the next instruction in the trace or \b
+ /// LLDB_INVALID_ADDRESS if not available.
+ ///
+ /// \return
+ /// The control flow categories, or \b 0 if the instruction is an error.
+ lldb::TraceInstructionControlFlowType
+ GetControlFlowType(lldb::addr_t next_load_address) const;
+
IntelPTInstruction(IntelPTInstruction &&other) = default;
private:
@@ -95,6 +113,7 @@ private:
const IntelPTInstruction &operator=(const IntelPTInstruction &other) = delete;
pt_insn m_pt_insn;
+ llvm::Optional<uint64_t> m_timestamp;
std::unique_ptr<llvm::ErrorInfoBase> m_error;
};
@@ -105,11 +124,15 @@ private:
///
/// Each decoded thread contains a cursor to the current position the user is
/// stopped at. See \a Trace::GetCursorPosition for more information.
-class DecodedThread {
+class DecodedThread : public std::enable_shared_from_this<DecodedThread> {
public:
- DecodedThread(std::vector<IntelPTInstruction> &&instructions)
- : m_instructions(std::move(instructions)), m_position(GetLastPosition()) {
- }
+ DecodedThread(lldb::ThreadSP thread_sp,
+ std::vector<IntelPTInstruction> &&instructions,
+ size_t raw_trace_size);
+
+ /// Constructor with a single error signaling a complete failure of the
+ /// decoding process.
+ DecodedThread(lldb::ThreadSP thread_sp, llvm::Error error);
/// Get the instructions from the decoded trace. Some of them might indicate
/// errors (i.e. gaps) in the trace.
@@ -118,28 +141,23 @@ public:
/// The instructions of the trace.
llvm::ArrayRef<IntelPTInstruction> GetInstructions() const;
- /// \return
- /// The current position of the cursor of this trace, or 0 if there are no
- /// instructions.
- size_t GetCursorPosition() const;
+ /// Get a new cursor for the decoded thread.
+ lldb::TraceCursorUP GetCursor();
- /// Change the position of the cursor of this trace. If this value is to high,
- /// the new position will be set as the last instruction of the trace.
+ /// Get the size in bytes of the corresponding Intel PT raw trace
///
/// \return
- /// The effective new position.
- size_t SetCursorPosition(size_t new_position);
- /// \}
+ /// The size of the trace.
+ size_t GetRawTraceSize() const;
private:
- /// \return
- /// The index of the last element of the trace, or 0 if empty.
- size_t GetLastPosition() const;
-
+ lldb::ThreadSP m_thread_sp;
std::vector<IntelPTInstruction> m_instructions;
- size_t m_position;
+ size_t m_raw_trace_size;
};
+using DecodedThreadSP = std::shared_ptr<DecodedThread>;
+
} // namespace trace_intel_pt
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
index b6e8ae808632..3827881454c7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
@@ -1,5 +1,4 @@
-//===-- IntelPTDecoder.cpp --------------------------------------*- C++ -*-===//
-//
+//===-- IntelPTDecoder.cpp --======----------------------------------------===//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -10,10 +9,13 @@
#include "llvm/Support/MemoryBuffer.h"
+#include "../common/ThreadPostMortemTrace.h"
+#include "DecodedThread.h"
+#include "TraceIntelPT.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadTrace.h"
+#include "lldb/Utility/StringExtractor.h"
using namespace lldb;
using namespace lldb_private;
@@ -85,7 +87,7 @@ static int ProcessPTEvents(pt_insn_decoder &decoder, int errcode) {
return errcode;
}
return 0;
-};
+}
/// Decode all the instructions from a configured decoder.
/// The decoding flow is based on
@@ -135,7 +137,23 @@ DecodeInstructions(pt_insn_decoder &decoder) {
break;
}
- instructions.emplace_back(insn);
+ uint64_t time;
+ int time_error = pt_insn_time(&decoder, &time, nullptr, nullptr);
+ if (time_error == -pte_invalid) {
+ // This happens if we invoke the pt_insn_time method incorrectly,
+ // but the instruction is good though.
+ instructions.emplace_back(
+ make_error<IntelPTError>(time_error, insn.ip));
+ instructions.emplace_back(insn);
+ break;
+ }
+ if (time_error == -pte_no_time) {
+ // We simply don't have time information, i.e. None of TSC, MTC or CYC
+ // was enabled.
+ instructions.emplace_back(insn);
+ } else {
+ instructions.emplace_back(insn, time);
+ }
}
}
@@ -158,39 +176,26 @@ static int ReadProcessMemory(uint8_t *buffer, size_t size,
return bytes_read;
}
-static std::vector<IntelPTInstruction> makeInstructionListFromError(Error err) {
- std::vector<IntelPTInstruction> instructions;
- instructions.emplace_back(std::move(err));
- return instructions;
-}
-
-static std::vector<IntelPTInstruction>
-CreateDecoderAndDecode(Process &process, const pt_cpu &pt_cpu,
- const FileSpec &trace_file) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error =
- MemoryBuffer::getFile(trace_file.GetPath());
- if (std::error_code err = trace_or_error.getError())
- return makeInstructionListFromError(errorCodeToError(err));
-
- MemoryBuffer &trace = **trace_or_error;
+static Expected<std::vector<IntelPTInstruction>>
+DecodeInMemoryTrace(Process &process, TraceIntelPT &trace_intel_pt,
+ MutableArrayRef<uint8_t> buffer) {
+ Expected<pt_cpu> cpu_info = trace_intel_pt.GetCPUInfo();
+ if (!cpu_info)
+ return cpu_info.takeError();
pt_config config;
pt_config_init(&config);
- config.cpu = pt_cpu;
+ config.cpu = *cpu_info;
if (int errcode = pt_cpu_errata(&config.errata, &config.cpu))
- return makeInstructionListFromError(make_error<IntelPTError>(errcode));
+ return make_error<IntelPTError>(errcode);
- // The libipt library does not modify the trace buffer, hence the following
- // cast is safe.
- config.begin =
- reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart()));
- config.end =
- reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferEnd()));
+ config.begin = buffer.data();
+ config.end = buffer.data() + buffer.size();
pt_insn_decoder *decoder = pt_insn_alloc_decoder(&config);
if (!decoder)
- return makeInstructionListFromError(make_error<IntelPTError>(-pte_nomem));
+ return make_error<IntelPTError>(-pte_nomem);
pt_image *image = pt_insn_get_image(decoder);
@@ -204,12 +209,71 @@ CreateDecoderAndDecode(Process &process, const pt_cpu &pt_cpu,
return instructions;
}
-const DecodedThread &ThreadTraceDecoder::Decode() {
- if (!m_decoded_thread.hasValue()) {
- m_decoded_thread = DecodedThread(
- CreateDecoderAndDecode(*m_trace_thread->GetProcess(), m_pt_cpu,
- m_trace_thread->GetTraceFile()));
- }
+static Expected<std::vector<IntelPTInstruction>>
+DecodeTraceFile(Process &process, TraceIntelPT &trace_intel_pt,
+ const FileSpec &trace_file, size_t &raw_trace_size) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error =
+ MemoryBuffer::getFile(trace_file.GetPath());
+ if (std::error_code err = trace_or_error.getError())
+ return errorCodeToError(err);
+
+ MemoryBuffer &trace = **trace_or_error;
+ MutableArrayRef<uint8_t> trace_data(
+ // The libipt library does not modify the trace buffer, hence the
+ // following cast is safe.
+ reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart())),
+ trace.getBufferSize());
+ raw_trace_size = trace_data.size();
+ return DecodeInMemoryTrace(process, trace_intel_pt, trace_data);
+}
+
+static Expected<std::vector<IntelPTInstruction>>
+DecodeLiveThread(Thread &thread, TraceIntelPT &trace, size_t &raw_trace_size) {
+ Expected<std::vector<uint8_t>> buffer =
+ trace.GetLiveThreadBuffer(thread.GetID());
+ if (!buffer)
+ return buffer.takeError();
+ raw_trace_size = buffer->size();
+ if (Expected<pt_cpu> cpu_info = trace.GetCPUInfo())
+ return DecodeInMemoryTrace(*thread.GetProcess(), trace,
+ MutableArrayRef<uint8_t>(*buffer));
+ else
+ return cpu_info.takeError();
+}
+DecodedThreadSP ThreadDecoder::Decode() {
+ if (!m_decoded_thread.hasValue())
+ m_decoded_thread = DoDecode();
return *m_decoded_thread;
}
+
+PostMortemThreadDecoder::PostMortemThreadDecoder(
+ const lldb::ThreadPostMortemTraceSP &trace_thread, TraceIntelPT &trace)
+ : m_trace_thread(trace_thread), m_trace(trace) {}
+
+DecodedThreadSP PostMortemThreadDecoder::DoDecode() {
+ size_t raw_trace_size = 0;
+ if (Expected<std::vector<IntelPTInstruction>> instructions =
+ DecodeTraceFile(*m_trace_thread->GetProcess(), m_trace,
+ m_trace_thread->GetTraceFile(), raw_trace_size))
+ return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(),
+ std::move(*instructions),
+ raw_trace_size);
+ else
+ return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(),
+ instructions.takeError());
+}
+
+LiveThreadDecoder::LiveThreadDecoder(Thread &thread, TraceIntelPT &trace)
+ : m_thread_sp(thread.shared_from_this()), m_trace(trace) {}
+
+DecodedThreadSP LiveThreadDecoder::DoDecode() {
+ size_t raw_trace_size = 0;
+ if (Expected<std::vector<IntelPTInstruction>> instructions =
+ DecodeLiveThread(*m_thread_sp, m_trace, raw_trace_size))
+ return std::make_shared<DecodedThread>(
+ m_thread_sp, std::move(*instructions), raw_trace_size);
+ else
+ return std::make_shared<DecodedThread>(m_thread_sp,
+ instructions.takeError());
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
index 2e67f9bf6da7..e969db579e52 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
@@ -12,38 +12,73 @@
#include "intel-pt.h"
#include "DecodedThread.h"
+#include "forward-declarations.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
namespace lldb_private {
namespace trace_intel_pt {
-/// \a lldb_private::ThreadTrace decoder that stores the output from decoding,
-/// avoiding recomputations, as decoding is expensive.
-class ThreadTraceDecoder {
+/// Base class that handles the decoding of a thread and caches the result.
+class ThreadDecoder {
public:
- /// \param[in] trace_thread
- /// The thread whose trace file will be decoded.
+ virtual ~ThreadDecoder() = default;
+
+ ThreadDecoder() = default;
+
+ /// Decode the thread and store the result internally, to avoid
+ /// recomputations.
///
- /// \param[in] pt_cpu
- /// The libipt cpu used when recording the trace.
- ThreadTraceDecoder(const std::shared_ptr<ThreadTrace> &trace_thread,
- const pt_cpu &pt_cpu)
- : m_trace_thread(trace_thread), m_pt_cpu(pt_cpu), m_decoded_thread() {}
+ /// \return
+ /// A \a DecodedThread instance.
+ DecodedThreadSP Decode();
- /// Decode the thread and store the result internally.
+ ThreadDecoder(const ThreadDecoder &other) = delete;
+ ThreadDecoder &operator=(const ThreadDecoder &other) = delete;
+
+protected:
+ /// Decode the thread.
///
/// \return
/// A \a DecodedThread instance.
- const DecodedThread &Decode();
+ virtual DecodedThreadSP DoDecode() = 0;
+
+ llvm::Optional<DecodedThreadSP> m_decoded_thread;
+};
+
+/// Decoder implementation for \a lldb_private::ThreadPostMortemTrace, which are
+/// non-live processes that come trace session files.
+class PostMortemThreadDecoder : public ThreadDecoder {
+public:
+ /// \param[in] trace_thread
+ /// The thread whose trace file will be decoded.
+ ///
+ /// \param[in] trace
+ /// The main Trace object who owns this decoder and its data.
+ PostMortemThreadDecoder(const lldb::ThreadPostMortemTraceSP &trace_thread,
+ TraceIntelPT &trace);
+
+private:
+ DecodedThreadSP DoDecode() override;
+
+ lldb::ThreadPostMortemTraceSP m_trace_thread;
+ TraceIntelPT &m_trace;
+};
+
+class LiveThreadDecoder : public ThreadDecoder {
+public:
+ /// \param[in] thread
+ /// The thread whose traces will be decoded.
+ ///
+ /// \param[in] trace
+ /// The main Trace object who owns this decoder and its data.
+ LiveThreadDecoder(Thread &thread, TraceIntelPT &trace);
private:
- ThreadTraceDecoder(const ThreadTraceDecoder &other) = delete;
- ThreadTraceDecoder &operator=(const ThreadTraceDecoder &other) = delete;
+ DecodedThreadSP DoDecode() override;
- std::shared_ptr<ThreadTrace> m_trace_thread;
- pt_cpu m_pt_cpu;
- llvm::Optional<DecodedThread> m_decoded_thread;
+ lldb::ThreadSP m_thread_sp;
+ TraceIntelPT &m_trace;
};
} // namespace trace_intel_pt
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
new file mode 100644
index 000000000000..edefdd0d3486
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
@@ -0,0 +1,100 @@
+//===-- TraceCursorIntelPT.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TraceCursorIntelPT.h"
+#include "DecodedThread.h"
+#include "TraceIntelPT.h"
+
+#include <cstdlib>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::trace_intel_pt;
+using namespace llvm;
+
+TraceCursorIntelPT::TraceCursorIntelPT(ThreadSP thread_sp,
+ DecodedThreadSP decoded_thread_sp)
+ : TraceCursor(thread_sp), m_decoded_thread_sp(decoded_thread_sp) {
+ assert(!m_decoded_thread_sp->GetInstructions().empty() &&
+ "a trace should have at least one instruction or error");
+ m_pos = m_decoded_thread_sp->GetInstructions().size() - 1;
+}
+
+size_t TraceCursorIntelPT::GetInternalInstructionSize() {
+ return m_decoded_thread_sp->GetInstructions().size();
+}
+
+bool TraceCursorIntelPT::Next() {
+ auto canMoveOne = [&]() {
+ if (IsForwards())
+ return m_pos + 1 < GetInternalInstructionSize();
+ return m_pos > 0;
+ };
+
+ size_t initial_pos = m_pos;
+
+ while (canMoveOne()) {
+ m_pos += IsForwards() ? 1 : -1;
+ if (!m_ignore_errors && IsError())
+ return true;
+ if (GetInstructionControlFlowType() & m_granularity)
+ return true;
+ }
+
+ // Didn't find any matching instructions
+ m_pos = initial_pos;
+ return false;
+}
+
+size_t TraceCursorIntelPT::Seek(int64_t offset, SeekType origin) {
+ int64_t last_index = GetInternalInstructionSize() - 1;
+
+ auto fitPosToBounds = [&](int64_t raw_pos) -> int64_t {
+ return std::min(std::max((int64_t)0, raw_pos), last_index);
+ };
+
+ switch (origin) {
+ case TraceCursor::SeekType::Set:
+ m_pos = fitPosToBounds(offset);
+ return m_pos;
+ case TraceCursor::SeekType::End:
+ m_pos = fitPosToBounds(offset + last_index);
+ return last_index - m_pos;
+ case TraceCursor::SeekType::Current:
+ int64_t new_pos = fitPosToBounds(offset + m_pos);
+ int64_t dist = m_pos - new_pos;
+ m_pos = new_pos;
+ return std::abs(dist);
+ }
+}
+
+bool TraceCursorIntelPT::IsError() {
+ return m_decoded_thread_sp->GetInstructions()[m_pos].IsError();
+}
+
+Error TraceCursorIntelPT::GetError() {
+ return m_decoded_thread_sp->GetInstructions()[m_pos].ToError();
+}
+
+lldb::addr_t TraceCursorIntelPT::GetLoadAddress() {
+ return m_decoded_thread_sp->GetInstructions()[m_pos].GetLoadAddress();
+}
+
+Optional<uint64_t> TraceCursorIntelPT::GetTimestampCounter() {
+ return m_decoded_thread_sp->GetInstructions()[m_pos].GetTimestampCounter();
+}
+
+TraceInstructionControlFlowType
+TraceCursorIntelPT::GetInstructionControlFlowType() {
+ lldb::addr_t next_load_address =
+ m_pos + 1 < GetInternalInstructionSize()
+ ? m_decoded_thread_sp->GetInstructions()[m_pos + 1].GetLoadAddress()
+ : LLDB_INVALID_ADDRESS;
+ return m_decoded_thread_sp->GetInstructions()[m_pos].GetControlFlowType(
+ next_load_address);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
new file mode 100644
index 000000000000..29d3792bb489
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
@@ -0,0 +1,50 @@
+//===-- TraceCursorIntelPT.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H
+
+#include "IntelPTDecoder.h"
+#include "TraceIntelPTSessionFileParser.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceCursorIntelPT : public TraceCursor {
+public:
+ TraceCursorIntelPT(lldb::ThreadSP thread_sp,
+ DecodedThreadSP decoded_thread_sp);
+
+ size_t Seek(int64_t offset, SeekType origin) override;
+
+ virtual bool Next() override;
+
+ llvm::Error GetError() override;
+
+ lldb::addr_t GetLoadAddress() override;
+
+ llvm::Optional<uint64_t> GetTimestampCounter() override;
+
+ lldb::TraceInstructionControlFlowType
+ GetInstructionControlFlowType() override;
+
+ bool IsError() override;
+
+private:
+ size_t GetInternalInstructionSize();
+
+ /// Storage of the actual instructions
+ DecodedThreadSP m_decoded_thread_sp;
+ /// Internal instruction index currently pointing at.
+ size_t m_pos;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
index 63a8b2dff4a7..c12bcd3523e3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -8,12 +8,14 @@
#include "TraceIntelPT.h"
+#include "../common/ThreadPostMortemTrace.h"
#include "CommandObjectTraceStartIntelPT.h"
+#include "DecodedThread.h"
+#include "TraceIntelPTConstants.h"
#include "TraceIntelPTSessionFileParser.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadTrace.h"
using namespace lldb;
using namespace lldb_private;
@@ -22,18 +24,27 @@ using namespace llvm;
LLDB_PLUGIN_DEFINE(TraceIntelPT)
-CommandObjectSP GetStartCommand(CommandInterpreter &interpreter) {
- return CommandObjectSP(new CommandObjectTraceStartIntelPT(interpreter));
+lldb::CommandObjectSP
+TraceIntelPT::GetProcessTraceStartCommand(CommandInterpreter &interpreter) {
+ return CommandObjectSP(
+ new CommandObjectProcessTraceStartIntelPT(*this, interpreter));
+}
+
+lldb::CommandObjectSP
+TraceIntelPT::GetThreadTraceStartCommand(CommandInterpreter &interpreter) {
+ return CommandObjectSP(
+ new CommandObjectThreadTraceStartIntelPT(*this, interpreter));
}
void TraceIntelPT::Initialize() {
- PluginManager::RegisterPlugin(
- GetPluginNameStatic(), "Intel Processor Trace", CreateInstance,
- TraceIntelPTSessionFileParser::GetSchema(), GetStartCommand);
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Intel Processor Trace",
+ CreateInstanceForSessionFile,
+ CreateInstanceForLiveProcess,
+ TraceIntelPTSessionFileParser::GetSchema());
}
void TraceIntelPT::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
+ PluginManager::UnregisterPlugin(CreateInstanceForSessionFile);
}
ConstString TraceIntelPT::GetPluginNameStatic() {
@@ -55,60 +66,278 @@ uint32_t TraceIntelPT::GetPluginVersion() { return 1; }
void TraceIntelPT::Dump(Stream *s) const {}
-Expected<TraceSP>
-TraceIntelPT::CreateInstance(const json::Value &trace_session_file,
- StringRef session_file_dir, Debugger &debugger) {
+Expected<TraceSP> TraceIntelPT::CreateInstanceForSessionFile(
+ const json::Value &trace_session_file, StringRef session_file_dir,
+ Debugger &debugger) {
return TraceIntelPTSessionFileParser(debugger, trace_session_file,
session_file_dir)
.Parse();
}
+Expected<TraceSP> TraceIntelPT::CreateInstanceForLiveProcess(Process &process) {
+ TraceSP instance(new TraceIntelPT(process));
+ process.GetTarget().SetTrace(instance);
+ return instance;
+}
+
TraceIntelPT::TraceIntelPT(
- const pt_cpu &pt_cpu,
- const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads)
- : m_pt_cpu(pt_cpu) {
- for (const std::shared_ptr<ThreadTrace> &thread : traced_threads)
- m_trace_threads.emplace(
- std::piecewise_construct,
- std::forward_as_tuple(thread->GetProcess()->GetID(), thread->GetID()),
- std::forward_as_tuple(thread, pt_cpu));
-}
-
-const DecodedThread *TraceIntelPT::Decode(const Thread &thread) {
- auto it = m_trace_threads.find(
- std::make_pair(thread.GetProcess()->GetID(), thread.GetID()));
- if (it == m_trace_threads.end())
- return nullptr;
- return &it->second.Decode();
-}
-
-size_t TraceIntelPT::GetCursorPosition(const Thread &thread) {
- const DecodedThread *decoded_thread = Decode(thread);
- if (!decoded_thread)
- return 0;
- return decoded_thread->GetCursorPosition();
-}
-
-void TraceIntelPT::TraverseInstructions(
- const Thread &thread, size_t position, TraceDirection direction,
- std::function<bool(size_t index, Expected<lldb::addr_t> load_addr)>
- callback) {
- const DecodedThread *decoded_thread = Decode(thread);
- if (!decoded_thread)
- return;
+ const pt_cpu &cpu_info,
+ const std::vector<ThreadPostMortemTraceSP> &traced_threads)
+ : m_cpu_info(cpu_info) {
+ for (const ThreadPostMortemTraceSP &thread : traced_threads)
+ m_thread_decoders.emplace(
+ thread.get(), std::make_unique<PostMortemThreadDecoder>(thread, *this));
+}
+
+DecodedThreadSP TraceIntelPT::Decode(Thread &thread) {
+ RefreshLiveProcessState();
+ if (m_live_refresh_error.hasValue())
+ return std::make_shared<DecodedThread>(
+ thread.shared_from_this(),
+ createStringError(inconvertibleErrorCode(), *m_live_refresh_error));
+
+ auto it = m_thread_decoders.find(&thread);
+ if (it == m_thread_decoders.end())
+ return std::make_shared<DecodedThread>(
+ thread.shared_from_this(),
+ createStringError(inconvertibleErrorCode(), "thread not traced"));
+ return it->second->Decode();
+}
- ArrayRef<IntelPTInstruction> instructions = decoded_thread->GetInstructions();
+lldb::TraceCursorUP TraceIntelPT::GetCursor(Thread &thread) {
+ return Decode(thread)->GetCursor();
+}
- ssize_t delta = direction == TraceDirection::Forwards ? 1 : -1;
- for (ssize_t i = position; i < (ssize_t)instructions.size() && i >= 0;
- i += delta)
- if (!callback(i, instructions[i].GetLoadAddress()))
- break;
+void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
+ Optional<size_t> raw_size = GetRawTraceSize(thread);
+ s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+ if (!raw_size) {
+ s.Printf(", not traced\n");
+ return;
+ }
+ s.Printf("\n Raw trace size: %zu bytes\n", *raw_size);
+ return;
}
-size_t TraceIntelPT::GetInstructionCount(const Thread &thread) {
- if (const DecodedThread *decoded_thread = Decode(thread))
- return decoded_thread->GetInstructions().size();
+Optional<size_t> TraceIntelPT::GetRawTraceSize(Thread &thread) {
+ if (IsTraced(thread))
+ return Decode(thread)->GetRawTraceSize();
else
- return 0;
+ return None;
+}
+
+Expected<pt_cpu> TraceIntelPT::GetCPUInfoForLiveProcess() {
+ Expected<std::vector<uint8_t>> cpu_info = GetLiveProcessBinaryData("cpuInfo");
+ if (!cpu_info)
+ return cpu_info.takeError();
+
+ int64_t cpu_family = -1;
+ int64_t model = -1;
+ int64_t stepping = -1;
+ std::string vendor_id;
+
+ StringRef rest(reinterpret_cast<const char *>(cpu_info->data()),
+ cpu_info->size());
+ 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;
+ }
+
+ if ((cpu_family != -1) && (model != -1) && (stepping != -1) &&
+ (!vendor_id.empty())) {
+ return pt_cpu{vendor_id == "GenuineIntel" ? pcv_intel : pcv_unknown,
+ static_cast<uint16_t>(cpu_family),
+ static_cast<uint8_t>(model),
+ static_cast<uint8_t>(stepping)};
+ }
+ }
+ return createStringError(inconvertibleErrorCode(),
+ "Failed parsing the target's /proc/cpuinfo file");
+}
+
+Expected<pt_cpu> TraceIntelPT::GetCPUInfo() {
+ if (!m_cpu_info) {
+ if (llvm::Expected<pt_cpu> cpu_info = GetCPUInfoForLiveProcess())
+ m_cpu_info = *cpu_info;
+ else
+ return cpu_info.takeError();
+ }
+ return *m_cpu_info;
+}
+
+void TraceIntelPT::DoRefreshLiveProcessState(
+ Expected<TraceGetStateResponse> state) {
+ m_thread_decoders.clear();
+
+ if (!state) {
+ m_live_refresh_error = toString(state.takeError());
+ return;
+ }
+
+ for (const TraceThreadState &thread_state : state->tracedThreads) {
+ Thread &thread =
+ *m_live_process->GetThreadList().FindThreadByID(thread_state.tid);
+ m_thread_decoders.emplace(
+ &thread, std::make_unique<LiveThreadDecoder>(thread, *this));
+ }
+}
+
+bool TraceIntelPT::IsTraced(const Thread &thread) {
+ RefreshLiveProcessState();
+ return m_thread_decoders.count(&thread);
+}
+
+// The information here should match the description of the intel-pt section
+// of the jLLDBTraceStart packet in the lldb/docs/lldb-gdb-remote.txt
+// documentation file. Similarly, it should match the CLI help messages of the
+// TraceIntelPTOptions.td file.
+const char *TraceIntelPT::GetStartConfigurationHelp() {
+ return R"(Parameters:
+
+ Note: If a parameter is not specified, a default value will be used.
+
+ - int threadBufferSize (defaults to 4096 bytes):
+ [process and thread tracing]
+ Trace size in bytes per thread. It must be a power of 2 greater
+ than or equal to 4096 (2^12). The trace is circular keeping the
+ the most recent data.
+
+ - boolean enableTsc (default to false):
+ [process and thread tracing]
+ Whether to use enable TSC timestamps or not. This is supported on
+ all devices that support intel-pt.
+
+ - psbPeriod (defaults to null):
+ [process and thread tracing]
+ This value defines the period in which PSB packets will be generated.
+ A PSB packet is a synchronization packet that contains a TSC
+ timestamp and the current absolute instruction pointer.
+
+ This parameter can only be used if
+
+ /sys/bus/event_source/devices/intel_pt/caps/psb_cyc
+
+ is 1. Otherwise, the PSB period will be defined by the processor.
+
+ If supported, valid values for this period can be found in
+
+ /sys/bus/event_source/devices/intel_pt/caps/psb_periods
+
+ which contains a hexadecimal number, whose bits represent
+ valid values e.g. if bit 2 is set, then value 2 is valid.
+
+ The psb_period value is converted to the approximate number of
+ raw trace bytes between PSB packets as:
+
+ 2 ^ (value + 11)
+
+ e.g. value 3 means 16KiB between PSB packets. Defaults to 0 if
+ supported.
+
+ - int processBufferSizeLimit (defaults to 500 MB):
+ [process tracing only]
+ Maximum total trace size per process in bytes. This limit applies
+ to the sum of the sizes of all thread traces of this process,
+ excluding the ones created explicitly with "thread tracing".
+ Whenever a thread is attempted to be traced due to this command
+ and the limit would be reached, the process is stopped with a
+ "processor trace" reason, so that the user can retrace the process
+ if needed.)";
+}
+
+Error TraceIntelPT::Start(size_t thread_buffer_size,
+ size_t total_buffer_size_limit, bool enable_tsc,
+ Optional<size_t> psb_period) {
+ TraceIntelPTStartRequest request;
+ request.threadBufferSize = thread_buffer_size;
+ request.processBufferSizeLimit = total_buffer_size_limit;
+ request.enableTsc = enable_tsc;
+ request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; });
+ request.type = GetPluginName().AsCString();
+ return Trace::Start(toJSON(request));
+}
+
+Error TraceIntelPT::Start(StructuredData::ObjectSP configuration) {
+ size_t thread_buffer_size = kDefaultThreadBufferSize;
+ size_t process_buffer_size_limit = kDefaultProcessBufferSizeLimit;
+ bool enable_tsc = kDefaultEnableTscValue;
+ Optional<size_t> psb_period = kDefaultPsbPeriod;
+
+ if (configuration) {
+ if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) {
+ dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size);
+ dict->GetValueForKeyAsInteger("processBufferSizeLimit",
+ process_buffer_size_limit);
+ dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc);
+ dict->GetValueForKeyAsInteger("psbPeriod", psb_period);
+ } else {
+ return createStringError(inconvertibleErrorCode(),
+ "configuration object is not a dictionary");
+ }
+ }
+
+ return Start(thread_buffer_size, process_buffer_size_limit, enable_tsc,
+ psb_period);
+}
+
+llvm::Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids,
+ size_t thread_buffer_size, bool enable_tsc,
+ Optional<size_t> psb_period) {
+ TraceIntelPTStartRequest request;
+ request.threadBufferSize = thread_buffer_size;
+ request.enableTsc = enable_tsc;
+ request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; });
+ request.type = GetPluginName().AsCString();
+ request.tids.emplace();
+ for (lldb::tid_t tid : tids)
+ request.tids->push_back(tid);
+ return Trace::Start(toJSON(request));
+}
+
+Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids,
+ StructuredData::ObjectSP configuration) {
+ size_t thread_buffer_size = kDefaultThreadBufferSize;
+ bool enable_tsc = kDefaultEnableTscValue;
+ Optional<size_t> psb_period = kDefaultPsbPeriod;
+
+ if (configuration) {
+ if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) {
+ dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size);
+ dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc);
+ dict->GetValueForKeyAsInteger("psbPeriod", psb_period);
+ } else {
+ return createStringError(inconvertibleErrorCode(),
+ "configuration object is not a dictionary");
+ }
+ }
+
+ return Start(tids, thread_buffer_size, enable_tsc, psb_period);
+}
+
+Expected<std::vector<uint8_t>>
+TraceIntelPT::GetLiveThreadBuffer(lldb::tid_t tid) {
+ return Trace::GetLiveThreadBinaryData(tid, "threadTraceBuffer");
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
index 5058e6fd32f2..e3b247112ae1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -45,49 +45,134 @@ public:
/// \return
/// A trace instance or an error in case of failures.
static llvm::Expected<lldb::TraceSP>
- CreateInstance(const llvm::json::Value &trace_session_file,
- llvm::StringRef session_file_dir, Debugger &debugger);
+ CreateInstanceForSessionFile(const llvm::json::Value &trace_session_file,
+ llvm::StringRef session_file_dir,
+ Debugger &debugger);
+
+ static llvm::Expected<lldb::TraceSP>
+ CreateInstanceForLiveProcess(Process &process);
static ConstString GetPluginNameStatic();
uint32_t GetPluginVersion() override;
/// \}
+ lldb::CommandObjectSP
+ GetProcessTraceStartCommand(CommandInterpreter &interpreter) override;
+
+ lldb::CommandObjectSP
+ GetThreadTraceStartCommand(CommandInterpreter &interpreter) override;
+
llvm::StringRef GetSchema() override;
- void TraverseInstructions(
- const Thread &thread, size_t position, TraceDirection direction,
- std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)>
- callback) override;
+ lldb::TraceCursorUP GetCursor(Thread &thread) override;
+
+ void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override;
+
+ llvm::Optional<size_t> GetRawTraceSize(Thread &thread);
+
+ void DoRefreshLiveProcessState(
+ llvm::Expected<TraceGetStateResponse> state) override;
+
+ bool IsTraced(const Thread &thread) override;
+
+ const char *GetStartConfigurationHelp() override;
+
+ /// Start tracing a live process.
+ ///
+ /// \param[in] thread_buffer_size
+ /// Trace size per thread in bytes.
+ ///
+ /// \param[in] total_buffer_size_limit
+ /// Maximum total trace size per process in bytes.
+ /// More information in TraceIntelPT::GetStartConfigurationHelp().
+ ///
+ /// \param[in] enable_tsc
+ /// Whether to use enable TSC timestamps or not.
+ /// More information in TraceIntelPT::GetStartConfigurationHelp().
+ ///
+ /// \param[in] psb_period
+ ///
+ /// This value defines the period in which PSB packets will be generated.
+ /// More information in TraceIntelPT::GetStartConfigurationHelp();
+ ///
+ /// \return
+ /// \a llvm::Error::success if the operation was successful, or
+ /// \a llvm::Error otherwise.
+ llvm::Error Start(size_t thread_buffer_size, size_t total_buffer_size_limit,
+ bool enable_tsc, llvm::Optional<size_t> psb_period);
+
+ /// \copydoc Trace::Start
+ llvm::Error Start(StructuredData::ObjectSP configuration =
+ StructuredData::ObjectSP()) override;
- size_t GetInstructionCount(const Thread &thread) override;
+ /// Start tracing live threads.
+ ///
+ /// \param[in] tids
+ /// Threads to trace.
+ ///
+ /// \param[in] thread_buffer_size
+ /// Trace size per thread in bytes.
+ ///
+ /// \param[in] enable_tsc
+ /// Whether to use enable TSC timestamps or not.
+ /// More information in TraceIntelPT::GetStartConfigurationHelp().
+ ///
+ /// \param[in] psb_period
+ ///
+ /// This value defines the period in which PSB packets will be generated.
+ /// More information in TraceIntelPT::GetStartConfigurationHelp().
+ ///
+ /// \return
+ /// \a llvm::Error::success if the operation was successful, or
+ /// \a llvm::Error otherwise.
+ llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, size_t thread_buffer_size,
+ bool enable_tsc, llvm::Optional<size_t> psb_period);
+
+ /// \copydoc Trace::Start
+ llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids,
+ StructuredData::ObjectSP configuration =
+ StructuredData::ObjectSP()) override;
+
+ /// Get the thread buffer content for a live thread
+ llvm::Expected<std::vector<uint8_t>> GetLiveThreadBuffer(lldb::tid_t tid);
- size_t GetCursorPosition(const Thread &thread) override;
+ llvm::Expected<pt_cpu> GetCPUInfo();
private:
friend class TraceIntelPTSessionFileParser;
+ llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess();
+
/// \param[in] trace_threads
/// ThreadTrace instances, which are not live-processes and whose trace
/// files are fixed.
- TraceIntelPT(const pt_cpu &pt_cpu,
- const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads);
+ TraceIntelPT(
+ const pt_cpu &cpu_info,
+ const std::vector<lldb::ThreadPostMortemTraceSP> &traced_threads);
+
+ /// Constructor for live processes
+ TraceIntelPT(Process &live_process)
+ : Trace(live_process), m_thread_decoders(){};
/// Decode the trace of the given thread that, i.e. recontruct the traced
- /// instructions. That trace must be managed by this class.
+ /// instructions.
///
/// \param[in] thread
/// If \a thread is a \a ThreadTrace, then its internal trace file will be
/// decoded. Live threads are not currently supported.
///
/// \return
- /// A \a DecodedThread instance if decoding was successful, or a \b
- /// nullptr if the thread's trace is not managed by this class.
- const DecodedThread *Decode(const Thread &thread);
-
- pt_cpu m_pt_cpu;
- std::map<std::pair<lldb::pid_t, lldb::tid_t>, ThreadTraceDecoder>
- m_trace_threads;
+ /// A \a DecodedThread shared pointer with the decoded instructions. Any
+ /// errors are embedded in the instruction list.
+ DecodedThreadSP Decode(Thread &thread);
+
+ /// It is provided by either a session file or a live process' "cpuInfo"
+ /// binary data.
+ llvm::Optional<pt_cpu> m_cpu_info;
+ std::map<const Thread *, std::unique_ptr<ThreadDecoder>> m_thread_decoders;
+ /// Error gotten after a failed live process update, if any.
+ llvm::Optional<std::string> m_live_refresh_error;
};
} // namespace trace_intel_pt
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h
new file mode 100644
index 000000000000..c2bc1b57b2bd
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h
@@ -0,0 +1,27 @@
+//===-- TraceIntelPTConstants.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
+
+#include <cstddef>
+
+#include <llvm/ADT/Optional.h>
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+const size_t kDefaultThreadBufferSize = 4 * 1024; // 4KB
+const size_t kDefaultProcessBufferSizeLimit = 5 * 1024 * 1024; // 500MB
+const bool kDefaultEnableTscValue = false;
+const llvm::Optional<size_t> kDefaultPsbPeriod = llvm::None;
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
index 6ffe949dbe7b..9e8cab1ee5c4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
@@ -1,16 +1,74 @@
include "../../../../source/Commands/OptionsBase.td"
+// The information of the start commands here should match the description of
+// the intel-pt section of the jLLDBTraceStart packet in the
+// lldb/docs/lldb-gdb-remote.txt documentation file. Similarly, it should match
+// the API help message of TraceIntelPT::GetStartConfigurationHelp().
+
let Command = "thread trace start intel pt" in {
def thread_trace_start_intel_pt_size: Option<"size", "s">,
Group<1>,
Arg<"Value">,
- Desc<"The size of the trace in KB. The kernel rounds it down to the nearest"
- " multiple of 4. Defaults to 4.">;
- def thread_trace_start_intel_pt_custom_config: Option<"custom-config", "c">,
+ Desc<"Trace size in bytes per thread. It must be a power of 2 greater "
+ "than or equal to 4096 (2^12). The trace is circular keeping "
+ "the most recent data. Defaults to 4096 bytes.">;
+ def thread_trace_start_intel_pt_tsc: Option<"tsc", "t">,
+ Group<1>,
+ Desc<"Enable the use of TSC timestamps. This is supported on all devices "
+ "that support intel-pt.">;
+ def thread_trace_start_intel_pt_psb_period: Option<"psb-period", "p">,
+ Group<1>,
+ Arg<"Value">,
+ Desc<"This value defines the period in which PSB packets will be "
+ "generated. A PSB packet is a synchronization packet that contains a "
+ "TSC timestamp and the current absolute instruction pointer. "
+ "This parameter can only be used if "
+ "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc is 1. Otherwise, "
+ "the PSB period will be defined by the processor. If supported, valid "
+ "values for this period can be found in "
+ "/sys/bus/event_source/devices/intel_pt/caps/psb_periods which "
+ "contains a hexadecimal number, whose bits represent valid values "
+ "e.g. if bit 2 is set, then value 2 is valid. The psb_period value is "
+ "converted to the approximate number of raw trace bytes between PSB "
+ "packets as: 2 ^ (value + 11), e.g. value 3 means 16KiB between PSB "
+ "packets. Defaults to 0 if supported.">;
+}
+
+let Command = "process trace start intel pt" in {
+ def process_trace_start_intel_pt_thread_size: Option<"thread-size", "s">,
+ Group<1>,
+ Arg<"Value">,
+ Desc<"Trace size in bytes per thread. It must be a power of 2 greater "
+ "than or equal to 4096 (2^12). The trace is circular keeping "
+ "the most recent data. Defaults to 4096 bytes.">;
+ def process_trace_start_intel_pt_process_size_limit: Option<"total-size-limit", "l">,
+ Group<1>,
+ Arg<"Value">,
+ Desc<"Maximum total trace size per process in bytes. This limit applies to "
+ "the sum of the sizes of all thread traces of this process, excluding "
+ "the ones created with the \"thread trace start\" command. "
+ "Whenever a thread is attempted to be traced due to this command and "
+ "the limit would be reached, the process is stopped with a "
+ "\"processor trace\" reason, so that the user can retrace the process "
+ "if needed. Defaults to 500MB.">;
+ def process_trace_start_intel_pt_tsc: Option<"tsc", "t">,
+ Group<1>,
+ Desc<"Enable the use of TSC timestamps. This is supported on all devices "
+ "that support intel-pt.">;
+ def process_trace_start_intel_pt_psb_period: Option<"psb-period", "p">,
Group<1>,
Arg<"Value">,
- Desc<"Low level bitmask configuration for the kernel based on the values "
- "in `grep -H /sys/bus/event_source/devices/intel_pt/format/*`. "
- "See https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/perf-intel-pt.txt"
- " for more information. Defaults to 0.">;
+ Desc<"This value defines the period in which PSB packets will be "
+ "generated. A PSB packet is a synchronization packet that contains a "
+ "TSC timestamp and the current absolute instruction pointer. "
+ "This parameter can only be used if "
+ "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc is 1. Otherwise, "
+ "the PSB period will be defined by the processor. If supported, valid "
+ "values for this period can be found in "
+ "/sys/bus/event_source/devices/intel_pt/caps/psb_periods which "
+ "contains a hexadecimal number, whose bits represent valid values "
+ "e.g. if bit 2 is set, then value 2 is valid. The psb_period value is "
+ "converted to the approximate number of raw trace bytes between PSB "
+ "packets as: 2 ^ (value + 11), e.g. value 3 means 16KiB between PSB "
+ "packets. Defaults to 0 if supported.">;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
index beef5c3968ea..5af7c269d0cb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
@@ -8,11 +8,11 @@
#include "TraceIntelPTSessionFileParser.h"
+#include "../common/ThreadPostMortemTrace.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadList.h"
-#include "lldb/Target/ThreadTrace.h"
using namespace lldb;
using namespace lldb_private;
@@ -24,7 +24,7 @@ StringRef TraceIntelPTSessionFileParser::GetSchema() {
if (schema.empty()) {
schema = TraceSessionFileParser::BuildSchema(R"({
"type": "intel-pt",
- "pt_cpu": {
+ "cpuInfo": {
"vendor": "intel" | "unknown",
"family": integer,
"model": integer,
@@ -35,21 +35,22 @@ StringRef TraceIntelPTSessionFileParser::GetSchema() {
return schema;
}
-pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(const JSONPTCPU &pt_cpu) {
- return {pt_cpu.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
- static_cast<uint16_t>(pt_cpu.family),
- static_cast<uint8_t>(pt_cpu.model),
- static_cast<uint8_t>(pt_cpu.stepping)};
+pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(
+ const JSONTraceIntelPTCPUInfo &cpu_info) {
+ return {cpu_info.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
+ static_cast<uint16_t>(cpu_info.family),
+ static_cast<uint8_t>(cpu_info.model),
+ static_cast<uint8_t>(cpu_info.stepping)};
}
TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance(
- const pt_cpu &pt_cpu, std::vector<ParsedProcess> &parsed_processes) {
- std::vector<ThreadTraceSP> threads;
+ const pt_cpu &cpu_info, std::vector<ParsedProcess> &parsed_processes) {
+ std::vector<ThreadPostMortemTraceSP> threads;
for (const ParsedProcess &parsed_process : parsed_processes)
threads.insert(threads.end(), parsed_process.threads.begin(),
parsed_process.threads.end());
- TraceSP trace_instance(new TraceIntelPT(pt_cpu, threads));
+ TraceSP trace_instance(new TraceIntelPT(cpu_info, threads));
for (const ParsedProcess &parsed_process : parsed_processes)
parsed_process.target_sp->SetTrace(trace_instance);
@@ -64,7 +65,7 @@ Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() {
if (Expected<std::vector<ParsedProcess>> parsed_processes =
ParseCommonSessionFile(session))
- return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.pt_cpu),
+ return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.cpuInfo),
*parsed_processes);
else
return parsed_processes.takeError();
@@ -73,25 +74,34 @@ Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() {
namespace llvm {
namespace json {
-bool fromJSON(const Value &value,
- TraceIntelPTSessionFileParser::JSONPTCPU &pt_cpu, Path path) {
- ObjectMapper o(value, path);
- return o && o.map("vendor", pt_cpu.vendor) &&
- o.map("family", pt_cpu.family) && o.map("model", pt_cpu.model) &&
- o.map("stepping", pt_cpu.stepping);
-}
-
bool fromJSON(
const Value &value,
TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings &plugin_settings,
Path path) {
ObjectMapper o(value, path);
- return o && o.map("pt_cpu", plugin_settings.pt_cpu) &&
+ return o && o.map("cpuInfo", plugin_settings.cpuInfo) &&
fromJSON(
value,
(TraceSessionFileParser::JSONTracePluginSettings &)plugin_settings,
path);
}
+bool fromJSON(const json::Value &value,
+ TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("vendor", cpu_info.vendor) &&
+ o.map("family", cpu_info.family) && o.map("model", cpu_info.model) &&
+ o.map("stepping", cpu_info.stepping);
+}
+
+Value toJSON(
+ const TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info) {
+ return Value(Object{{"family", cpu_info.family},
+ {"model", cpu_info.model},
+ {"stepping", cpu_info.stepping},
+ {"vendor", cpu_info.vendor}});
+}
+
} // namespace json
} // namespace llvm
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
index 6a896de09d00..b2667a882222 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
@@ -10,7 +10,8 @@
#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
#include "TraceIntelPT.h"
-#include "lldb/Target/TraceSessionFileParser.h"
+
+#include "../common/TraceSessionFileParser.h"
namespace lldb_private {
namespace trace_intel_pt {
@@ -19,16 +20,16 @@ class TraceIntelPT;
class TraceIntelPTSessionFileParser : public TraceSessionFileParser {
public:
- struct JSONPTCPU {
- std::string vendor;
+ struct JSONTraceIntelPTCPUInfo {
int64_t family;
int64_t model;
int64_t stepping;
+ std::string vendor;
};
struct JSONTraceIntelPTSettings
: TraceSessionFileParser::JSONTracePluginSettings {
- JSONPTCPU pt_cpu;
+ JSONTraceIntelPTCPUInfo cpuInfo;
};
/// See \a TraceSessionFileParser::TraceSessionFileParser for the description
@@ -52,11 +53,11 @@ public:
llvm::Expected<lldb::TraceSP> Parse();
lldb::TraceSP
- CreateTraceIntelPTInstance(const pt_cpu &pt_cpu,
+ CreateTraceIntelPTInstance(const pt_cpu &cpu_info,
std::vector<ParsedProcess> &parsed_processes);
private:
- pt_cpu ParsePTCPU(const JSONPTCPU &pt_cpu);
+ static pt_cpu ParsePTCPU(const JSONTraceIntelPTCPUInfo &cpu_info);
const llvm::json::Value &m_trace_session_file;
};
@@ -67,17 +68,20 @@ private:
namespace llvm {
namespace json {
-bool fromJSON(
- const Value &value,
- lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::JSONPTCPU
- &pt_cpu,
- Path path);
-
bool fromJSON(const Value &value,
lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::
JSONTraceIntelPTSettings &plugin_settings,
Path path);
+bool fromJSON(const llvm::json::Value &value,
+ lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::
+ JSONTraceIntelPTCPUInfo &packet,
+ llvm::json::Path path);
+
+llvm::json::Value
+toJSON(const lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::
+ JSONTraceIntelPTCPUInfo &packet);
+
} // namespace json
} // namespace llvm
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h
new file mode 100644
index 000000000000..3c5f811acc10
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h
@@ -0,0 +1,20 @@
+//===-- forward-declarations.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceIntelPT;
+class ThreadDecoder;
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
new file mode 100644
index 000000000000..3dd4c89e2777
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
@@ -0,0 +1,66 @@
+//===-- CommandObjectThreadTraceExportCTF.cpp -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectThreadTraceExportCTF.h"
+
+#include "lldb/Host/OptionParser.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::ctf;
+using namespace llvm;
+
+// CommandObjectThreadTraceExportCTF
+
+#define LLDB_OPTIONS_thread_trace_export_ctf
+#include "TraceExporterCTFCommandOptions.inc"
+
+Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 't': {
+ int64_t thread_index;
+ if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) ||
+ thread_index < 0)
+ error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_thread_index = thread_index;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+}
+
+void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ m_thread_index = None;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_thread_trace_export_ctf_options);
+}
+
+bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
+ CommandReturnObject &result) {
+ Stream &s = result.GetOutputStream();
+ // TODO: create an actual instance of the exporter and invoke it
+ if (m_options.m_thread_index)
+ s.Printf("got thread index %d\n", (int)m_options.m_thread_index.getValue());
+ else
+ s.Printf("didn't get a thread index\n");
+
+ return result.Succeeded();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
new file mode 100644
index 000000000000..26b068a8f8c5
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
@@ -0,0 +1,56 @@
+//===-- CommandObjectThreadTraceExportCTF.h -------------------*- C++ //-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
+
+#include "TraceExporterCTF.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+namespace lldb_private {
+namespace ctf {
+
+class CommandObjectThreadTraceExportCTF : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ llvm::Optional<size_t> m_thread_index;
+ };
+
+ CommandObjectThreadTraceExportCTF(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "thread trace export ctf",
+ "Export a given thread's trace to Chrome Trace Format",
+ "thread trace export ctf [<ctf-options>]",
+ lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
+ lldb::eCommandProcessMustBeLaunched |
+ lldb::eCommandProcessMustBePaused),
+ m_options() {}
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
+
+ CommandOptions m_options;
+};
+
+} // namespace ctf
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
new file mode 100644
index 000000000000..08bc03d78303
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
@@ -0,0 +1,53 @@
+//===-- TraceExporterCTF.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TraceExporterCTF.h"
+
+#include <memory>
+
+#include "CommandObjectThreadTraceExportCTF.h"
+#include "lldb/Core/PluginManager.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::ctf;
+using namespace llvm;
+
+LLDB_PLUGIN_DEFINE(TraceExporterCTF)
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+static CommandObjectSP
+GetThreadTraceExportCommand(CommandInterpreter &interpreter) {
+ return std::make_shared<CommandObjectThreadTraceExportCTF>(interpreter);
+}
+
+void TraceExporterCTF::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "Chrome Trace Format Exporter", CreateInstance,
+ GetThreadTraceExportCommand);
+}
+
+void TraceExporterCTF::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString TraceExporterCTF::GetPluginNameStatic() {
+ static ConstString g_name("ctf");
+ return g_name;
+}
+
+ConstString TraceExporterCTF::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t TraceExporterCTF::GetPluginVersion() { return 1; }
+
+Expected<TraceExporterUP> TraceExporterCTF::CreateInstance() {
+ return std::make_unique<TraceExporterCTF>();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
new file mode 100644
index 000000000000..8f9e354ab0dd
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
@@ -0,0 +1,42 @@
+//===-- TraceExporterCTF.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
+#define LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
+
+#include "lldb/Target/TraceExporter.h"
+
+namespace lldb_private {
+namespace ctf {
+
+/// Trace Exporter Plugin that can produce traces in Chrome Trace Format.
+/// Still in development.
+class TraceExporterCTF : public TraceExporter {
+public:
+ ~TraceExporterCTF() override = default;
+
+ /// PluginInterface protocol
+ /// \{
+ static llvm::Expected<lldb::TraceExporterUP> CreateInstance();
+
+ ConstString GetPluginName() override;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+
+ uint32_t GetPluginVersion() override;
+ /// \}
+};
+
+} // namespace ctf
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
new file mode 100644
index 000000000000..ce751f148d9f
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
@@ -0,0 +1,9 @@
+include "../../../../source/Commands/OptionsBase.td"
+
+let Command = "thread trace export ctf" in {
+ def thread_trace_export_ctf: Option<"tid", "t">,
+ Group<1>,
+ Arg<"ThreadIndex">,
+ Desc<"Export the trace for the specified thread index. Otherwise, the "
+ "currently selected thread will be used.">;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 0218606b8937..d4260a966857 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -75,7 +75,7 @@
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
-#include <stdio.h>
+#include <cstdio>
#include <mutex>
@@ -163,7 +163,6 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
if (auto *baseDtorDecl = base_record->getDestructor()) {
if (baseDtorDecl->isVirtual()) {
- path.Decls = baseDtorDecl;
decls.push_back(baseDtorDecl);
return true;
} else
@@ -171,12 +170,11 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
}
// Otherwise, search for name in the base class.
- for (path.Decls = base_record->lookup(name); !path.Decls.empty();
- path.Decls = path.Decls.slice(1)) {
+ for (path.Decls = base_record->lookup(name).begin();
+ path.Decls != path.Decls.end(); ++path.Decls) {
if (auto *method_decl =
- llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
+ llvm::dyn_cast<clang::CXXMethodDecl>(*path.Decls))
if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
- path.Decls = method_decl;
decls.push_back(method_decl);
return true;
}
@@ -479,6 +477,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
case clang::Language::OpenCL:
LangStd = LangStandard::lang_opencl10;
break;
+ case clang::Language::OpenCLCXX:
+ LangStd = LangStandard::lang_openclcpp;
+ break;
case clang::Language::CUDA:
LangStd = LangStandard::lang_cuda;
break;
@@ -686,8 +687,8 @@ void TypeSystemClang::SetTargetTriple(llvm::StringRef target_triple) {
void TypeSystemClang::SetExternalSource(
llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
ASTContext &ast = getASTContext();
- ast.setExternalSource(ast_source_up);
ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
+ ast.setExternalSource(ast_source_up);
}
ASTContext &TypeSystemClang::getASTContext() {
@@ -745,7 +746,7 @@ void TypeSystemClang::CreateASTContext() {
*m_diagnostics_engine_up, *m_file_manager_up);
m_ast_up = std::make_unique<ASTContext>(
*m_language_options_up, *m_source_manager_up, *m_identifier_table_up,
- *m_selector_table_up, *m_builtins_up);
+ *m_selector_table_up, *m_builtins_up, TU_Complete);
m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>();
m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false);
@@ -1356,9 +1357,11 @@ CompilerType TypeSystemClang::CreateRecordType(
}
namespace {
- bool IsValueParam(const clang::TemplateArgument &argument) {
- return argument.getKind() == TemplateArgument::Integral;
- }
+/// Returns true iff the given TemplateArgument should be represented as an
+/// NonTypeTemplateParmDecl in the AST.
+bool IsValueParam(const clang::TemplateArgument &argument) {
+ return argument.getKind() == TemplateArgument::Integral;
+}
}
static TemplateParameterList *CreateTemplateParameterList(
@@ -1462,6 +1465,99 @@ void TypeSystemClang::CreateFunctionTemplateSpecializationInfo(
template_args_ptr, nullptr);
}
+/// Returns true if the given template parameter can represent the given value.
+/// For example, `typename T` can represent `int` but not integral values such
+/// as `int I = 3`.
+static bool TemplateParameterAllowsValue(NamedDecl *param,
+ const TemplateArgument &value) {
+ if (auto *type_param = llvm::dyn_cast<TemplateTypeParmDecl>(param)) {
+ // Compare the argument kind, i.e. ensure that <typename> != <int>.
+ if (value.getKind() != TemplateArgument::Type)
+ return false;
+ } else if (auto *type_param =
+ llvm::dyn_cast<NonTypeTemplateParmDecl>(param)) {
+ // Compare the argument kind, i.e. ensure that <typename> != <int>.
+ if (!IsValueParam(value))
+ return false;
+ // Compare the integral type, i.e. ensure that <int> != <char>.
+ if (type_param->getType() != value.getIntegralType())
+ return false;
+ } else {
+ // There is no way to create other parameter decls at the moment, so we
+ // can't reach this case during normal LLDB usage. Log that this happened
+ // and assert.
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ LLDB_LOG(log,
+ "Don't know how to compare template parameter to passed"
+ " value. Decl kind of parameter is: {0}",
+ param->getDeclKindName());
+ lldbassert(false && "Can't compare this TemplateParmDecl subclass");
+ // In release builds just fall back to marking the parameter as not
+ // accepting the value so that we don't try to fit an instantiation to a
+ // template that doesn't fit. E.g., avoid that `S<1>` is being connected to
+ // `template<typename T> struct S;`.
+ return false;
+ }
+ return true;
+}
+
+/// Returns true if the given class template declaration could produce an
+/// instantiation with the specified values.
+/// For example, `<typename T>` allows the arguments `float`, but not for
+/// example `bool, float` or `3` (as an integer parameter value).
+static bool ClassTemplateAllowsToInstantiationArgs(
+ ClassTemplateDecl *class_template_decl,
+ const TypeSystemClang::TemplateParameterInfos &instantiation_values) {
+
+ TemplateParameterList &params = *class_template_decl->getTemplateParameters();
+
+ // Save some work by iterating only once over the found parameters and
+ // calculate the information related to parameter packs.
+
+ // Contains the first pack parameter (or non if there are none).
+ llvm::Optional<NamedDecl *> pack_parameter;
+ // Contains the number of non-pack parameters.
+ size_t non_pack_params = params.size();
+ for (size_t i = 0; i < params.size(); ++i) {
+ NamedDecl *param = params.getParam(i);
+ if (param->isParameterPack()) {
+ pack_parameter = param;
+ non_pack_params = i;
+ break;
+ }
+ }
+
+ // The found template needs to have compatible non-pack template arguments.
+ // E.g., ensure that <typename, typename> != <typename>.
+ // The pack parameters are compared later.
+ if (non_pack_params != instantiation_values.args.size())
+ return false;
+
+ // Ensure that <typename...> != <typename>.
+ if (pack_parameter.hasValue() != instantiation_values.hasParameterPack())
+ return false;
+
+ // Compare the first pack parameter that was found with the first pack
+ // parameter value. The special case of having an empty parameter pack value
+ // always fits to a pack parameter.
+ // E.g., ensure that <int...> != <typename...>.
+ if (pack_parameter && !instantiation_values.packed_args->args.empty() &&
+ !TemplateParameterAllowsValue(
+ *pack_parameter, instantiation_values.packed_args->args.front()))
+ return false;
+
+ // Compare all the non-pack parameters now.
+ // E.g., ensure that <int> != <long>.
+ for (const auto pair : llvm::zip_first(instantiation_values.args, params)) {
+ const TemplateArgument &passed_arg = std::get<0>(pair);
+ NamedDecl *found_param = std::get<1>(pair);
+ if (!TemplateParameterAllowsValue(found_param, passed_arg))
+ return false;
+ }
+
+ return class_template_decl;
+}
+
ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
DeclContext *decl_ctx, OptionalClangModuleID owning_module,
lldb::AccessType access_type, const char *class_name, int kind,
@@ -1475,12 +1571,22 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
IdentifierInfo &identifier_info = ast.Idents.get(class_name);
DeclarationName decl_name(&identifier_info);
+ // Search the AST for an existing ClassTemplateDecl that could be reused.
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
-
for (NamedDecl *decl : result) {
class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
- if (class_template_decl)
- return class_template_decl;
+ if (!class_template_decl)
+ continue;
+ // The class template has to be able to represents the instantiation
+ // values we received. Without this we might end up putting an instantiation
+ // with arguments such as <int, int> to a template such as:
+ // template<typename T> struct S;
+ // Connecting the instantiation to an incompatible template could cause
+ // problems later on.
+ if (!ClassTemplateAllowsToInstantiationArgs(class_template_decl,
+ template_param_infos))
+ continue;
+ return class_template_decl;
}
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
@@ -1866,8 +1972,8 @@ TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
SetOwningModule(using_decl, owning_module);
clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
- getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
- target);
+ getASTContext(), current_decl_ctx, clang::SourceLocation(),
+ target->getDeclName(), using_decl, target);
SetOwningModule(shadow_decl, owning_module);
using_decl->addShadowDecl(shadow_decl);
current_decl_ctx->addDecl(using_decl);
@@ -2114,11 +2220,10 @@ ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
return decl;
}
-void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl,
- ParmVarDecl **params,
- unsigned num_params) {
+void TypeSystemClang::SetFunctionParameters(
+ FunctionDecl *function_decl, llvm::ArrayRef<ParmVarDecl *> params) {
if (function_decl)
- function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
+ function_decl->setParams(params);
}
CompilerType
@@ -2470,42 +2575,6 @@ ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) {
return nullptr;
}
-bool TypeSystemClang::SetTagTypeKind(clang::QualType tag_qual_type,
- int kind) const {
- const clang::Type *clang_type = tag_qual_type.getTypePtr();
- if (clang_type) {
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
- if (tag_type) {
- clang::TagDecl *tag_decl =
- llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
- if (tag_decl) {
- tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
- return true;
- }
- }
- }
- return false;
-}
-
-bool TypeSystemClang::SetDefaultAccessForRecordFields(
- clang::RecordDecl *record_decl, int default_accessibility,
- int *assigned_accessibilities, size_t num_assigned_accessibilities) {
- if (record_decl) {
- uint32_t field_idx;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(),
- field_end = record_decl->field_end(), field_idx = 0;
- field != field_end; ++field, ++field_idx) {
- // If no accessibility was assigned, assign the correct one
- if (field_idx < num_assigned_accessibilities &&
- assigned_accessibilities[field_idx] == clang::AS_none)
- field->setAccess((clang::AccessSpecifier)default_accessibility);
- }
- return true;
- }
- return false;
-}
-
clang::DeclContext *
TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
return GetDeclContextForType(ClangUtil::GetQualType(type));
@@ -4697,7 +4766,6 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Void:
break;
- case clang::BuiltinType::Bool:
case clang::BuiltinType::Char_S:
case clang::BuiltinType::SChar:
case clang::BuiltinType::WChar_S:
@@ -4708,6 +4776,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Int128:
return lldb::eEncodingSint;
+ case clang::BuiltinType::Bool:
case clang::BuiltinType::Char_U:
case clang::BuiltinType::UChar:
case clang::BuiltinType::WChar_U:
@@ -4889,6 +4958,75 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::SveFloat64x4:
break;
+ // RISC-V V builtin types.
+ case clang::BuiltinType::RvvInt8mf8:
+ case clang::BuiltinType::RvvInt8mf4:
+ case clang::BuiltinType::RvvInt8mf2:
+ case clang::BuiltinType::RvvInt8m1:
+ case clang::BuiltinType::RvvInt8m2:
+ case clang::BuiltinType::RvvInt8m4:
+ case clang::BuiltinType::RvvInt8m8:
+ case clang::BuiltinType::RvvUint8mf8:
+ case clang::BuiltinType::RvvUint8mf4:
+ case clang::BuiltinType::RvvUint8mf2:
+ case clang::BuiltinType::RvvUint8m1:
+ case clang::BuiltinType::RvvUint8m2:
+ case clang::BuiltinType::RvvUint8m4:
+ case clang::BuiltinType::RvvUint8m8:
+ case clang::BuiltinType::RvvInt16mf4:
+ case clang::BuiltinType::RvvInt16mf2:
+ case clang::BuiltinType::RvvInt16m1:
+ case clang::BuiltinType::RvvInt16m2:
+ case clang::BuiltinType::RvvInt16m4:
+ case clang::BuiltinType::RvvInt16m8:
+ case clang::BuiltinType::RvvUint16mf4:
+ case clang::BuiltinType::RvvUint16mf2:
+ case clang::BuiltinType::RvvUint16m1:
+ case clang::BuiltinType::RvvUint16m2:
+ case clang::BuiltinType::RvvUint16m4:
+ case clang::BuiltinType::RvvUint16m8:
+ case clang::BuiltinType::RvvInt32mf2:
+ case clang::BuiltinType::RvvInt32m1:
+ case clang::BuiltinType::RvvInt32m2:
+ case clang::BuiltinType::RvvInt32m4:
+ case clang::BuiltinType::RvvInt32m8:
+ case clang::BuiltinType::RvvUint32mf2:
+ case clang::BuiltinType::RvvUint32m1:
+ case clang::BuiltinType::RvvUint32m2:
+ case clang::BuiltinType::RvvUint32m4:
+ case clang::BuiltinType::RvvUint32m8:
+ case clang::BuiltinType::RvvInt64m1:
+ case clang::BuiltinType::RvvInt64m2:
+ case clang::BuiltinType::RvvInt64m4:
+ case clang::BuiltinType::RvvInt64m8:
+ case clang::BuiltinType::RvvUint64m1:
+ case clang::BuiltinType::RvvUint64m2:
+ case clang::BuiltinType::RvvUint64m4:
+ case clang::BuiltinType::RvvUint64m8:
+ case clang::BuiltinType::RvvFloat16mf4:
+ case clang::BuiltinType::RvvFloat16mf2:
+ case clang::BuiltinType::RvvFloat16m1:
+ case clang::BuiltinType::RvvFloat16m2:
+ case clang::BuiltinType::RvvFloat16m4:
+ case clang::BuiltinType::RvvFloat16m8:
+ case clang::BuiltinType::RvvFloat32mf2:
+ case clang::BuiltinType::RvvFloat32m1:
+ case clang::BuiltinType::RvvFloat32m2:
+ case clang::BuiltinType::RvvFloat32m4:
+ case clang::BuiltinType::RvvFloat32m8:
+ case clang::BuiltinType::RvvFloat64m1:
+ case clang::BuiltinType::RvvFloat64m2:
+ case clang::BuiltinType::RvvFloat64m4:
+ case clang::BuiltinType::RvvFloat64m8:
+ case clang::BuiltinType::RvvBool1:
+ case clang::BuiltinType::RvvBool2:
+ case clang::BuiltinType::RvvBool4:
+ case clang::BuiltinType::RvvBool8:
+ case clang::BuiltinType::RvvBool16:
+ case clang::BuiltinType::RvvBool32:
+ case clang::BuiltinType::RvvBool64:
+ break;
+
case clang::BuiltinType::IncompleteMatrixIdx:
break;
}
@@ -6365,7 +6503,7 @@ CompilerType TypeSystemClang::GetChildCompilerTypeAtIndex(
case clang::Type::RValueReference:
if (idx_is_valid) {
const clang::ReferenceType *reference_type =
- llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
+ llvm::cast<clang::ReferenceType>(GetQualType(type).getTypePtr());
CompilerType pointee_clang_type =
GetType(reference_type->getPointeeType());
if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
@@ -6536,10 +6674,11 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
if (cxx_record_decl->lookupInBases(
[decl_name](const clang::CXXBaseSpecifier *specifier,
clang::CXXBasePath &path) {
- path.Decls =
- specifier->getType()->getAsCXXRecordDecl()->lookup(
- decl_name);
- return !path.Decls.empty();
+ CXXRecordDecl *record =
+ specifier->getType()->getAsCXXRecordDecl();
+ auto r = record->lookup(decl_name);
+ path.Decls = r.begin();
+ return !r.empty();
},
paths)) {
clang::CXXBasePaths::const_paths_iterator path,
@@ -6562,9 +6701,10 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
->getDecl());
}
}
- for (clang::NamedDecl *path_decl : path->Decls) {
+ for (clang::DeclContext::lookup_iterator I = path->Decls, E;
+ I != E; ++I) {
child_idx = GetIndexForRecordChild(
- parent_record_decl, path_decl, omit_empty_base_classes);
+ parent_record_decl, *I, omit_empty_base_classes);
if (child_idx == UINT32_MAX) {
child_indexes.clear();
return 0;
@@ -9238,11 +9378,11 @@ CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName(
void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
std::vector<CompilerDecl> found_decls;
- if (opaque_decl_ctx) {
+ SymbolFile *symbol_file = GetSymbolFile();
+ if (opaque_decl_ctx && symbol_file) {
DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
std::set<DeclContext *> searched;
std::multimap<DeclContext *, DeclContext *> search_queue;
- SymbolFile *symbol_file = GetSymbolFile();
for (clang::DeclContext *decl_context = root_decl_ctx;
decl_context != nullptr && found_decls.empty();
@@ -9336,10 +9476,10 @@ uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
clang::DeclContext *child_decl_ctx,
ConstString *child_name,
CompilerType *child_type) {
- if (frame_decl_ctx) {
+ SymbolFile *symbol_file = GetSymbolFile();
+ if (frame_decl_ctx && symbol_file) {
std::set<DeclContext *> searched;
std::multimap<DeclContext *, DeclContext *> search_queue;
- SymbolFile *symbol_file = GetSymbolFile();
// Get the lookup scope for the decl we're trying to find.
clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
@@ -9585,7 +9725,8 @@ ScratchTypeSystemClang::ScratchTypeSystemClang(Target &target,
llvm::Triple triple)
: TypeSystemClang("scratch ASTContext", triple), m_triple(triple),
m_target_wp(target.shared_from_this()),
- m_persistent_variables(new ClangPersistentVariables) {
+ m_persistent_variables(
+ new ClangPersistentVariables(target.shared_from_this())) {
m_scratch_ast_source_up = CreateASTSource();
m_scratch_ast_source_up->InstallASTContext(*this);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
@@ -9653,7 +9794,8 @@ ScratchTypeSystemClang::CreateUtilityFunction(std::string text,
return {};
return std::make_unique<ClangUtilityFunction>(
- *target_sp.get(), std::move(text), std::move(name));
+ *target_sp.get(), std::move(text), std::move(name),
+ target_sp->GetDebugUtilityExpression());
}
PersistentExpressionState *
diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index d1d876d05a6b..4a6891795bd8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -9,7 +9,7 @@
#ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
#define LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
-#include <stdint.h>
+#include <cstdint>
#include <functional>
#include <initializer_list>
@@ -265,7 +265,7 @@ public:
clang::DeclContext::lookup_result result = decl_context->lookup(myName);
if (!result.empty()) {
- clang::NamedDecl *named_decl = result[0];
+ clang::NamedDecl *named_decl = *result.begin();
if (const RecordDeclType *record_decl =
llvm::dyn_cast<RecordDeclType>(named_decl))
compiler_type.SetCompilerType(
@@ -328,6 +328,8 @@ public:
(!packed_args || !packed_args->packed_args);
}
+ bool hasParameterPack() const { return static_cast<bool>(packed_args); }
+
llvm::SmallVector<const char *, 2> names;
llvm::SmallVector<clang::TemplateArgument, 2> args;
@@ -378,13 +380,6 @@ public:
bool isForwardDecl, bool isInternal,
ClangASTMetadata *metadata = nullptr);
- bool SetTagTypeKind(clang::QualType type, int kind) const;
-
- bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl,
- int default_accessibility,
- int *assigned_accessibilities,
- size_t num_assigned_accessibilities);
-
// Returns a mask containing bits from the TypeSystemClang::eTypeXXX
// enumerations
@@ -421,7 +416,7 @@ public:
int storage, bool add_decl = false);
void SetFunctionParameters(clang::FunctionDecl *function_decl,
- clang::ParmVarDecl **params, unsigned num_params);
+ llvm::ArrayRef<clang::ParmVarDecl *> params);
CompilerType CreateBlockPointerType(const CompilerType &function_type);
diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 1bc071c2b161..65947c5f833b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -38,10 +38,10 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
Status error;
- const bool prefer_file_cache = true;
+ const bool force_live_memory = true;
if (process_sp->GetTarget().ReadMemory(
- range.GetBaseAddress(), prefer_file_cache, function_text.data(),
- range.GetByteSize(), error) != range.GetByteSize()) {
+ range.GetBaseAddress(), function_text.data(), range.GetByteSize(),
+ error, force_live_memory) != range.GetByteSize()) {
return false;
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index fe1275d5b0cf..402a70cd025f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -51,12 +51,11 @@ bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly(
ProcessSP process_sp(thread.GetProcess());
if (process_sp.get() == nullptr)
return false;
- const bool prefer_file_cache = true;
std::vector<uint8_t> function_text(func.GetByteSize());
Status error;
if (process_sp->GetTarget().ReadMemory(
- func.GetBaseAddress(), prefer_file_cache, function_text.data(),
- func.GetByteSize(), error) == func.GetByteSize()) {
+ func.GetBaseAddress(), function_text.data(), func.GetByteSize(),
+ error) == func.GetByteSize()) {
RegisterContextSP reg_ctx(thread.GetRegisterContext());
m_assembly_inspection_engine->Initialize(reg_ctx);
return m_assembly_inspection_engine->GetNonCallSiteUnwindPlanFromAssembly(
@@ -153,12 +152,11 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
return false;
if (m_assembly_inspection_engine == nullptr)
return false;
- const bool prefer_file_cache = true;
std::vector<uint8_t> function_text(func.GetByteSize());
Status error;
if (process_sp->GetTarget().ReadMemory(
- func.GetBaseAddress(), prefer_file_cache, function_text.data(),
- func.GetByteSize(), error) == func.GetByteSize()) {
+ func.GetBaseAddress(), function_text.data(), func.GetByteSize(),
+ error) == func.GetByteSize()) {
RegisterContextSP reg_ctx(thread.GetRegisterContext());
m_assembly_inspection_engine->Initialize(reg_ctx);
return m_assembly_inspection_engine->AugmentUnwindPlanFromCallSite(
@@ -185,10 +183,9 @@ bool UnwindAssembly_x86::GetFastUnwindPlan(AddressRange &func, Thread &thread,
ProcessSP process_sp = thread.GetProcess();
if (process_sp) {
Target &target(process_sp->GetTarget());
- const bool prefer_file_cache = true;
Status error;
- if (target.ReadMemory(func.GetBaseAddress(), prefer_file_cache,
- opcode_data.data(), 4, error) == 4) {
+ if (target.ReadMemory(func.GetBaseAddress(), opcode_data.data(), 4,
+ error) == 4) {
uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
@@ -220,12 +217,10 @@ bool UnwindAssembly_x86::FirstNonPrologueInsn(
if (m_assembly_inspection_engine == nullptr)
return false;
- const bool prefer_file_cache = true;
std::vector<uint8_t> function_text(func.GetByteSize());
Status error;
- if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache,
- function_text.data(), func.GetByteSize(),
- error) == func.GetByteSize()) {
+ if (target->ReadMemory(func.GetBaseAddress(), function_text.data(),
+ func.GetByteSize(), error) == func.GetByteSize()) {
size_t offset;
if (m_assembly_inspection_engine->FindFirstNonPrologueInstruction(
function_text.data(), func.GetByteSize(), offset)) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
index f39dce1afaa6..487748812968 100644
--- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
+++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -45,9 +45,9 @@ public:
/// are called. This one takes a vector of register name and lldb
/// register numbers.
struct lldb_reg_info {
- const char *name;
- uint32_t lldb_regnum;
- lldb_reg_info() : name(nullptr), lldb_regnum(LLDB_INVALID_REGNUM) {}
+ const char *name = nullptr;
+ uint32_t lldb_regnum = LLDB_INVALID_REGNUM;
+ lldb_reg_info() = default;
};
void Initialize(std::vector<lldb_reg_info> &reg_info);