aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:11:55 +0000
commit5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch)
tree1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/lldb/source/Plugins
parent3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff)
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins')
-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.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp780
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h129
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp88
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp69
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp789
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h171
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp132
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h89
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp100
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp101
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h74
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp246
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp120
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h52
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp252
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h34
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp81
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp23
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp22
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp22
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp57
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp407
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h5
-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.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp32
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp311
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp258
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp26
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp150
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp22
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp202
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h86
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp141
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h39
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp181
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp104
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp475
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp82
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h48
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp)32
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h)16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp)34
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h)15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp)4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h)223
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp)42
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h (renamed from contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h)15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp211
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp58
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h203
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp520
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h92
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h26
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp26
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h50
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp599
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h268
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp81
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h32
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp67
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h46
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp150
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h25
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp42
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp129
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h77
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp38
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h25
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp668
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h397
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp95
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h228
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h36
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp65
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp1149
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.h68
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp142
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h54
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.cpp239
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.h64
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp661
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h35
231 files changed, 9786 insertions, 4434 deletions
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 283306ed0f81..025a7a3fc368 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
@@ -46,7 +46,7 @@ public:
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
- // Make sure the stack call frame addresses are are 8 byte aligned
+ // Make sure the stack call frame addresses are 8 byte aligned
if (cfa & (8ull - 1ull))
return false; // Not 8 byte aligned
if (cfa == 0)
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 b3d4cba795f0..01d4af62fa6e 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
@@ -49,7 +49,7 @@ public:
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
- // Make sure the stack call frame addresses are are 8 byte aligned
+ // Make sure the stack call frame addresses are 8 byte aligned
if (cfa & (8ull - 1ull))
return false; // Not 8 byte aligned
if (cfa == 0)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
index a77af75e57b8..c5ebd9717575 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
@@ -37,7 +37,7 @@ public:
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
- // Make sure the stack call frame addresses are are 4 byte aligned
+ // Make sure the stack call frame addresses are 4 byte aligned
if (cfa & (4ull - 1ull))
return false; // Not 4 byte aligned
if (cfa == 0)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
index ce67b367d18f..65bc3e0b6298 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
@@ -37,7 +37,7 @@ public:
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
- // Make sure the stack call frame addresses are are 4 byte aligned
+ // Make sure the stack call frame addresses are 4 byte aligned
if (cfa & (4ull - 1ull))
return false; // Not 4 byte aligned
if (cfa == 0)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
new file mode 100644
index 000000000000..6395f5bb5bd9
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
@@ -0,0 +1,780 @@
+//===-- ABISysV_riscv.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 "ABISysV_riscv.h"
+
+#include <array>
+#include <limits>
+
+#include "llvm/IR/DerivedTypes.h"
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString()
+#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString()
+
+// The ABI is not a source of such information as size, offset, encoding, etc.
+// of a register. Just provides correct dwarf and eh_frame numbers.
+
+#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num) \
+ { \
+ DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), 0, 0, \
+ eEncodingInvalid, eFormatDefault, \
+ {dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num}, \
+ nullptr, nullptr, nullptr, \
+ }
+
+#define DEFINE_REGISTER_STUB(dwarf_num, str_name) \
+ DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM)
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE_ADV(ABISysV_riscv, ABIRISCV)
+
+namespace {
+namespace dwarf {
+enum regnums {
+ zero,
+ ra,
+ sp,
+ gp,
+ tp,
+ t0,
+ t1,
+ t2,
+ fp,
+ s0 = fp,
+ s1,
+ a0,
+ a1,
+ a2,
+ a3,
+ a4,
+ a5,
+ a6,
+ a7,
+ s2,
+ s3,
+ s4,
+ s5,
+ s6,
+ s7,
+ s8,
+ s9,
+ s10,
+ s11,
+ t3,
+ t4,
+ t5,
+ t6,
+ pc
+};
+
+static const std::array<RegisterInfo, 33> g_register_infos = {
+ {DEFINE_REGISTER_STUB(zero, nullptr),
+ DEFINE_GENERIC_REGISTER_STUB(ra, nullptr, LLDB_REGNUM_GENERIC_RA),
+ DEFINE_GENERIC_REGISTER_STUB(sp, nullptr, LLDB_REGNUM_GENERIC_SP),
+ DEFINE_REGISTER_STUB(gp, nullptr),
+ DEFINE_REGISTER_STUB(tp, nullptr),
+ DEFINE_REGISTER_STUB(t0, nullptr),
+ DEFINE_REGISTER_STUB(t1, nullptr),
+ DEFINE_REGISTER_STUB(t2, nullptr),
+ DEFINE_GENERIC_REGISTER_STUB(fp, nullptr, LLDB_REGNUM_GENERIC_FP),
+ DEFINE_REGISTER_STUB(s1, nullptr),
+ DEFINE_GENERIC_REGISTER_STUB(a0, nullptr, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GENERIC_REGISTER_STUB(a1, nullptr, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GENERIC_REGISTER_STUB(a2, nullptr, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GENERIC_REGISTER_STUB(a3, nullptr, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GENERIC_REGISTER_STUB(a4, nullptr, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GENERIC_REGISTER_STUB(a5, nullptr, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GENERIC_REGISTER_STUB(a6, nullptr, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GENERIC_REGISTER_STUB(a7, nullptr, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_REGISTER_STUB(s2, nullptr),
+ DEFINE_REGISTER_STUB(s3, nullptr),
+ DEFINE_REGISTER_STUB(s4, nullptr),
+ DEFINE_REGISTER_STUB(s5, nullptr),
+ DEFINE_REGISTER_STUB(s6, nullptr),
+ DEFINE_REGISTER_STUB(s7, nullptr),
+ DEFINE_REGISTER_STUB(s8, nullptr),
+ DEFINE_REGISTER_STUB(s9, nullptr),
+ DEFINE_REGISTER_STUB(s10, nullptr),
+ DEFINE_REGISTER_STUB(s11, nullptr),
+ DEFINE_REGISTER_STUB(t3, nullptr),
+ DEFINE_REGISTER_STUB(t4, nullptr),
+ DEFINE_REGISTER_STUB(t5, nullptr),
+ DEFINE_REGISTER_STUB(t6, nullptr),
+ DEFINE_GENERIC_REGISTER_STUB(pc, nullptr, LLDB_REGNUM_GENERIC_PC)}};
+} // namespace dwarf
+} // namespace
+
+const RegisterInfo *ABISysV_riscv::GetRegisterInfoArray(uint32_t &count) {
+ count = dwarf::g_register_infos.size();
+ return dwarf::g_register_infos.data();
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+
+ABISP
+ABISysV_riscv::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
+ llvm::Triple::ArchType machine = arch.GetTriple().getArch();
+
+ if (llvm::Triple::riscv32 != machine && llvm::Triple::riscv64 != machine)
+ return ABISP();
+
+ ABISysV_riscv *abi = new ABISysV_riscv(std::move(process_sp),
+ MakeMCRegisterInfo(arch));
+ if (abi)
+ abi->SetIsRV64((llvm::Triple::riscv64 == machine) ? true : false);
+ return ABISP(abi);
+}
+
+static inline size_t AugmentArgSize(bool is_rv64, size_t size_in_bytes) {
+ size_t word_size = is_rv64 ? 8 : 4;
+ return llvm::alignTo(size_in_bytes, word_size);
+}
+
+static size_t
+TotalArgsSizeInWords(bool is_rv64,
+ const llvm::ArrayRef<ABI::CallArgument> &args) {
+ size_t reg_size = is_rv64 ? 8 : 4;
+ size_t word_size = reg_size;
+ size_t total_size = 0;
+ for (const auto &arg : args)
+ total_size +=
+ (ABI::CallArgument::TargetValue == arg.type ? AugmentArgSize(is_rv64,
+ arg.size)
+ : reg_size) /
+ word_size;
+
+ return total_size;
+}
+
+bool ABISysV_riscv::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ // TODO: Implement
+ return false;
+}
+
+bool ABISysV_riscv::PrepareTrivialCall(
+ Thread &thread, addr_t sp, addr_t pc, addr_t ra, llvm::Type &prototype,
+ llvm::ArrayRef<ABI::CallArgument> args) const {
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return false;
+
+ uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ if (pc_reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+ if (ra_reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ if (sp_reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ Status error;
+ ProcessSP process = thread.GetProcess();
+ if (!process)
+ return false;
+
+ size_t reg_size = m_is_rv64 ? 8 : 4;
+ size_t word_size = reg_size;
+ // Push host data onto target.
+ for (const auto &arg : args) {
+ // Skip over target values.
+ if (arg.type == ABI::CallArgument::TargetValue)
+ continue;
+
+ // Create space on the host stack for this data 4-byte aligned.
+ sp -= AugmentArgSize(m_is_rv64, arg.size);
+
+ if (process->WriteMemory(sp, arg.data_up.get(), arg.size, error) <
+ arg.size ||
+ error.Fail())
+ return false;
+
+ // Update the argument with the target pointer.
+ *const_cast<addr_t *>(&arg.value) = sp;
+ }
+
+ // Make sure number of parameters matches prototype.
+ assert(prototype.getFunctionNumParams() == args.size());
+
+ const size_t num_args = args.size();
+ const size_t regs_for_args_count = 8U;
+ const size_t num_args_in_regs =
+ num_args > regs_for_args_count ? regs_for_args_count : num_args;
+
+ // Number of arguments passed on stack.
+ size_t args_size = TotalArgsSizeInWords(m_is_rv64, args);
+ auto on_stack =
+ args_size <= regs_for_args_count ? 0 : args_size - regs_for_args_count;
+ auto offset = on_stack * word_size;
+
+ uint8_t reg_value[8];
+ size_t reg_index = LLDB_REGNUM_GENERIC_ARG1;
+
+ for (size_t i = 0; i < args_size; ++i) {
+ auto value = reinterpret_cast<const uint8_t *>(&args[i].value);
+ auto size =
+ ABI::CallArgument::TargetValue == args[i].type ? args[i].size : reg_size;
+
+ // Pass arguments via registers.
+ if (i < num_args_in_regs) {
+ // copy value to register, padding if arg is smaller than register
+ auto end = size < reg_size ? size : reg_size;
+ memcpy(reg_value, value, end);
+ if (reg_size > end)
+ memset(reg_value + end, 0, reg_size - end);
+
+ RegisterValue reg_val_obj(llvm::ArrayRef(reg_value, reg_size),
+ eByteOrderLittle);
+ if (!reg_ctx->WriteRegister(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_index),
+ reg_val_obj))
+ return false;
+
+ // NOTE: It's unsafe to iterate through LLDB_REGNUM_GENERICs
+ // But the "a" registers are sequential in the RISC-V register space
+ ++reg_index;
+ }
+
+ if (reg_index < regs_for_args_count || size == 0)
+ continue;
+
+ // Remaining arguments are passed on the stack.
+ if (process->WriteMemory(sp - offset, value, size, error) < size ||
+ !error.Success())
+ return false;
+
+ offset -= AugmentArgSize(m_is_rv64, size);
+ }
+
+ // Set stack pointer immediately below arguments.
+ sp -= on_stack * word_size;
+
+ // Update registers with current function call state.
+ reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
+ reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
+ reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
+
+ return true;
+}
+
+bool ABISysV_riscv::GetArgumentValues(Thread &thread, ValueList &values) const {
+ // TODO: Implement
+ return false;
+}
+
+Status ABISysV_riscv::SetReturnValueObject(StackFrameSP &frame_sp,
+ ValueObjectSP &new_value_sp) {
+ Status result;
+ if (!new_value_sp) {
+ result.SetErrorString("Empty value object for return value.");
+ return result;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ result.SetErrorString("Null clang type for return value.");
+ return result;
+ }
+
+ auto &reg_ctx = *frame_sp->GetThread()->GetRegisterContext();
+
+ bool is_signed = false;
+ if (!compiler_type.IsIntegerOrEnumerationType(is_signed) &&
+ !compiler_type.IsPointerType()) {
+ result.SetErrorString("We don't support returning other types at present");
+ return result;
+ }
+
+ DataExtractor data;
+ size_t num_bytes = new_value_sp->GetData(data, result);
+
+ if (result.Fail()) {
+ result.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s", result.AsCString());
+ return result;
+ }
+
+ size_t reg_size = m_is_rv64 ? 8 : 4;
+ if (num_bytes <= 2 * reg_size) {
+ offset_t offset = 0;
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ auto reg_info =
+ reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+ if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
+ result.SetErrorStringWithFormat("Couldn't write value to register %s",
+ reg_info->name);
+ return result;
+ }
+
+ if (num_bytes <= reg_size)
+ return result; // Successfully written.
+
+ // for riscv32, get the upper 32 bits from raw_value and write them
+ // for riscv64, get the next 64 bits from data and write them
+ if (4 == reg_size)
+ raw_value >>= 32;
+ else
+ raw_value = data.GetMaxU64(&offset, num_bytes - reg_size);
+ reg_info =
+ reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
+ result.SetErrorStringWithFormat("Couldn't write value to register %s",
+ reg_info->name);
+ }
+
+ return result;
+ }
+
+ result.SetErrorString(
+ "We don't support returning large integer values at present.");
+ return result;
+}
+
+template <typename T>
+static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) {
+ raw_value &= std::numeric_limits<T>::max();
+ if (is_signed)
+ scalar = static_cast<typename std::make_signed<T>::type>(raw_value);
+ else
+ scalar = static_cast<T>(raw_value);
+}
+
+static bool SetSizedInteger(Scalar &scalar, uint64_t raw_value,
+ uint8_t size_in_bytes, bool is_signed) {
+ switch (size_in_bytes) {
+ default:
+ return false;
+
+ case sizeof(uint64_t):
+ SetInteger<uint64_t>(scalar, raw_value, is_signed);
+ break;
+
+ case sizeof(uint32_t):
+ SetInteger<uint32_t>(scalar, raw_value, is_signed);
+ break;
+
+ case sizeof(uint16_t):
+ SetInteger<uint16_t>(scalar, raw_value, is_signed);
+ break;
+
+ case sizeof(uint8_t):
+ SetInteger<uint8_t>(scalar, raw_value, is_signed);
+ break;
+ }
+
+ return true;
+}
+
+static bool SetSizedFloat(Scalar &scalar, uint64_t raw_value,
+ uint8_t size_in_bytes) {
+ switch (size_in_bytes) {
+ default:
+ return false;
+
+ case sizeof(uint64_t):
+ scalar = *reinterpret_cast<double *>(&raw_value);
+ break;
+
+ case sizeof(uint32_t):
+ scalar = *reinterpret_cast<float *>(&raw_value);
+ break;
+ }
+
+ return true;
+}
+
+static ValueObjectSP GetValObjFromIntRegs(Thread &thread,
+ const RegisterContextSP &reg_ctx,
+ llvm::Triple::ArchType machine,
+ uint32_t type_flags,
+ uint32_t byte_size) {
+ Value value;
+ ValueObjectSP return_valobj_sp;
+ auto reg_info_a0 =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+ auto reg_info_a1 =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ uint64_t raw_value;
+
+ switch (byte_size) {
+ case sizeof(uint32_t):
+ // Read a0 to get the arg
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) & UINT32_MAX;
+ break;
+ case sizeof(uint64_t):
+ // Read a0 to get the arg on riscv64, a0 and a1 on riscv32
+ if (llvm::Triple::riscv32 == machine) {
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) & UINT32_MAX;
+ raw_value |=
+ (reg_ctx->ReadRegisterAsUnsigned(reg_info_a1, 0) & UINT32_MAX) << 32U;
+ } else {
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
+ }
+ break;
+ case 16: {
+ // Read a0 and a1 to get the arg on riscv64, not supported on riscv32
+ if (llvm::Triple::riscv32 == machine)
+ return return_valobj_sp;
+
+ // Create the ValueObjectSP here and return
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = thread.GetProcess()->GetByteOrder();
+ RegisterValue reg_value_a0, reg_value_a1;
+ if (reg_ctx->ReadRegister(reg_info_a0, reg_value_a0) &&
+ reg_ctx->ReadRegister(reg_info_a1, reg_value_a1)) {
+ Status error;
+ if (reg_value_a0.GetAsMemoryData(*reg_info_a0,
+ heap_data_up->GetBytes() + 0, 8,
+ byte_order, error) &&
+ reg_value_a1.GetAsMemoryData(*reg_info_a1,
+ heap_data_up->GetBytes() + 8, 8,
+ byte_order, error)) {
+ value.SetBytes(heap_data_up.release(), byte_size);
+ return ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ }
+ }
+ break;
+ }
+ default:
+ return return_valobj_sp;
+ }
+
+ if (type_flags & eTypeIsInteger) {
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
+ return return_valobj_sp;
+ } else if (type_flags & eTypeIsFloat) {
+ if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
+ return return_valobj_sp;
+ } else
+ return return_valobj_sp;
+
+ value.SetValueType(Value::ValueType::Scalar);
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ return return_valobj_sp;
+}
+
+static ValueObjectSP
+GetValObjFromFPRegs(Thread &thread, const RegisterContextSP &reg_ctx,
+ llvm::Triple::ArchType machine, uint32_t arch_fp_flags,
+ uint32_t type_flags, uint32_t byte_size) {
+ auto reg_info_fa0 = reg_ctx->GetRegisterInfoByName("fa0");
+ bool use_fp_regs = false;
+ ValueObjectSP return_valobj_sp;
+
+ switch (arch_fp_flags) {
+ // fp return value in integer registers a0 and possibly a1
+ case ArchSpec::eRISCV_float_abi_soft:
+ return_valobj_sp =
+ GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size);
+ return return_valobj_sp;
+ // fp return value in fp register fa0 (only float)
+ case ArchSpec::eRISCV_float_abi_single:
+ if (byte_size <= 4)
+ use_fp_regs = true;
+ break;
+ // fp return value in fp registers fa0 (float, double)
+ case ArchSpec::eRISCV_float_abi_double:
+ [[fallthrough]];
+ // fp return value in fp registers fa0 (float, double, quad)
+ // not implemented; act like they're doubles
+ case ArchSpec::eRISCV_float_abi_quad:
+ if (byte_size <= 8)
+ use_fp_regs = true;
+ break;
+ }
+
+ if (use_fp_regs) {
+ uint64_t raw_value;
+ Value value;
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_fa0, 0);
+ if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
+ return return_valobj_sp;
+ value.SetValueType(Value::ValueType::Scalar);
+ return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+ }
+ // we should never reach this, but if we do, use the integer registers
+ return GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size);
+}
+
+ValueObjectSP
+ABISysV_riscv::GetReturnValueObjectSimple(Thread &thread,
+ CompilerType &compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+
+ if (!compiler_type)
+ return return_valobj_sp;
+
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ Value value;
+ value.SetCompilerType(compiler_type);
+
+ const uint32_t type_flags = compiler_type.GetTypeInfo();
+ const size_t byte_size = compiler_type.GetByteSize(&thread).value_or(0);
+ const ArchSpec arch = thread.GetProcess()->GetTarget().GetArchitecture();
+ const llvm::Triple::ArchType machine = arch.GetMachine();
+
+ // Integer return type.
+ if (type_flags & eTypeIsInteger) {
+ return_valobj_sp =
+ GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size);
+ return return_valobj_sp;
+ }
+ // Pointer return type.
+ else if (type_flags & eTypeIsPointer) {
+ auto reg_info_a0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
+ value.SetValueType(Value::ValueType::Scalar);
+ return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+ }
+ // Floating point return type.
+ else if (type_flags & eTypeIsFloat) {
+ uint32_t float_count = 0;
+ bool is_complex = false;
+
+ if (compiler_type.IsFloatingPointType(float_count, is_complex) &&
+ float_count == 1 && !is_complex) {
+ const uint32_t arch_fp_flags =
+ arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask;
+ return_valobj_sp = GetValObjFromFPRegs(
+ thread, reg_ctx, machine, arch_fp_flags, type_flags, byte_size);
+ return return_valobj_sp;
+ }
+ }
+ // Unsupported return type.
+ return return_valobj_sp;
+}
+
+ValueObjectSP
+ABISysV_riscv::GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ llvm::Type &type) const {
+ Value value;
+ ValueObjectSP return_valobj_sp;
+
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ uint32_t type_flags = 0;
+ if (type.isIntegerTy())
+ type_flags = eTypeIsInteger;
+ else if (type.isVoidTy())
+ type_flags = eTypeIsPointer;
+ else if (type.isFloatTy())
+ type_flags = eTypeIsFloat;
+
+ const uint32_t byte_size = type.getPrimitiveSizeInBits() / CHAR_BIT;
+ const ArchSpec arch = thread.GetProcess()->GetTarget().GetArchitecture();
+ const llvm::Triple::ArchType machine = arch.GetMachine();
+
+ // Integer return type.
+ if (type_flags & eTypeIsInteger) {
+ return_valobj_sp =
+ GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size);
+ return return_valobj_sp;
+ }
+ // Pointer return type.
+ else if (type_flags & eTypeIsPointer) {
+ auto reg_info_a0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
+ value.SetValueType(Value::ValueType::Scalar);
+ return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+ }
+ // Floating point return type.
+ else if (type_flags & eTypeIsFloat) {
+ const uint32_t arch_fp_flags =
+ arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask;
+ return_valobj_sp = GetValObjFromFPRegs(
+ thread, reg_ctx, machine, arch_fp_flags, type_flags, byte_size);
+ return return_valobj_sp;
+ }
+ // Unsupported return type.
+ return return_valobj_sp;
+}
+
+ValueObjectSP ABISysV_riscv::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+
+ if (!return_compiler_type)
+ return return_valobj_sp;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ return GetReturnValueObjectSimple(thread, return_compiler_type);
+}
+
+bool ABISysV_riscv::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ uint32_t ra_reg_num = LLDB_REGNUM_GENERIC_RA;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Define CFA as the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ // Previous frame's pc is in ra
+
+ row->SetRegisterLocationToRegister(pc_reg_num, ra_reg_num, true);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("riscv function-entry unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
+}
+
+bool ABISysV_riscv::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindGeneric);
+
+ uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Define the CFA as the current frame pointer value.
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 0);
+ row->SetOffset(0);
+
+ int reg_size = 4;
+ if (m_is_rv64)
+ reg_size = 8;
+
+ // Assume the ra reg (return pc) and caller's frame pointer
+ // have been spilled to stack already.
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, reg_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, reg_size * -1, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("riscv default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
+}
+
+bool ABISysV_riscv::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
+}
+
+bool ABISysV_riscv::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (!reg_info)
+ return false;
+
+ const char *name = reg_info->name;
+ ArchSpec arch = GetProcessSP()->GetTarget().GetArchitecture();
+ uint32_t arch_flags = arch.GetFlags();
+ // floating point registers are only callee saved when using
+ // F, D or Q hardware floating point ABIs
+ bool is_hw_fp = (arch_flags & ArchSpec::eRISCV_float_abi_mask) != 0;
+
+ bool is_callee_saved =
+ llvm::StringSwitch<bool>(name)
+ // integer ABI names
+ .Cases("ra", "sp", "fp", true)
+ .Cases("s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9",
+ true)
+ .Cases("s10", "s11", true)
+ // integer hardware names
+ .Cases("x1", "x2", "x8", "x9", "x18", "x19", "x20", "x21", "x22",
+ true)
+ .Cases("x23", "x24", "x25", "x26", "x27", true)
+ // floating point ABI names
+ .Cases("fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
+ is_hw_fp)
+ .Cases("fs8", "fs9", "fs10", "fs11", is_hw_fp)
+ // floating point hardware names
+ .Cases("f8", "f9", "f18", "f19", "f20", "f21", "f22", "f23", is_hw_fp)
+ .Cases("f24", "f25", "f26", "f27", is_hw_fp)
+ .Default(false);
+
+ return is_callee_saved;
+}
+
+void ABISysV_riscv::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for RISCV targets", CreateInstance);
+}
+
+void ABISysV_riscv::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+static uint32_t GetGenericNum(llvm::StringRef name) {
+ return llvm::StringSwitch<uint32_t>(name)
+ .Case("pc", LLDB_REGNUM_GENERIC_PC)
+ .Cases("ra", "x1", LLDB_REGNUM_GENERIC_RA)
+ .Cases("sp", "x2", LLDB_REGNUM_GENERIC_SP)
+ .Cases("fp", "s0", LLDB_REGNUM_GENERIC_FP)
+ .Case("a0", LLDB_REGNUM_GENERIC_ARG1)
+ .Case("a1", LLDB_REGNUM_GENERIC_ARG2)
+ .Case("a2", LLDB_REGNUM_GENERIC_ARG3)
+ .Case("a3", LLDB_REGNUM_GENERIC_ARG4)
+ .Case("a4", LLDB_REGNUM_GENERIC_ARG5)
+ .Case("a5", LLDB_REGNUM_GENERIC_ARG6)
+ .Case("a6", LLDB_REGNUM_GENERIC_ARG7)
+ .Case("a7", LLDB_REGNUM_GENERIC_ARG8)
+ .Default(LLDB_INVALID_REGNUM);
+}
+
+void ABISysV_riscv::AugmentRegisterInfo(
+ std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) {
+ lldb_private::RegInfoBasedABI::AugmentRegisterInfo(regs);
+
+ for (auto it : llvm::enumerate(regs)) {
+ // Set alt name for certain registers for convenience
+ if (it.value().name == "zero")
+ it.value().alt_name.SetCString("x0");
+ else if (it.value().name == "ra")
+ it.value().alt_name.SetCString("x1");
+ else if (it.value().name == "sp")
+ it.value().alt_name.SetCString("x2");
+ else if (it.value().name == "gp")
+ it.value().alt_name.SetCString("x3");
+ else if (it.value().name == "fp")
+ it.value().alt_name.SetCString("s0");
+ else if (it.value().name == "s0")
+ it.value().alt_name.SetCString("x8");
+
+ // Set generic regnum so lldb knows what the PC, etc is
+ it.value().regnum_generic = GetGenericNum(it.value().name.GetStringRef());
+ }
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h b/contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
new file mode 100644
index 000000000000..d8cf008dbb0b
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
@@ -0,0 +1,129 @@
+//===-- ABISysV_riscv.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 liblldb_ABISysV_riscv_h_
+#define liblldb_ABISysV_riscv_h_
+
+// Other libraries and framework includes
+#include "llvm/TargetParser/Triple.h"
+
+// Project includes
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/lldb-private.h"
+
+class ABISysV_riscv : public lldb_private::RegInfoBasedABI {
+public:
+ ~ABISysV_riscv() override = default;
+
+ size_t GetRedZoneSize() const override { return 0; }
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ // Special thread plan for GDB style non-jit function calls.
+ bool
+ PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress, lldb::addr_t returnAddress,
+ llvm::Type &prototype,
+ llvm::ArrayRef<ABI::CallArgument> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Status
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ // Specialized to work with llvm IR types.
+ lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ llvm::Type &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // The CFA must be 128 bit aligned, unless the E ABI is used
+ lldb_private::ArchSpec arch = GetProcessSP()->GetTarget().GetArchitecture();
+ lldb_private::Flags arch_flags = arch.GetFlags();
+ if (arch_flags.Test(lldb_private::ArchSpec::eRISCV_rve))
+ return (cfa & 0x3ull) == 0;
+ return (cfa & 0xfull) == 0;
+ }
+
+ void SetIsRV64(bool is_rv64) { m_is_rv64 = is_rv64; }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Calls can use the least significant bit to store auxiliary information,
+ // so no strict check is done for alignment.
+
+ lldb_private::ArchSpec arch = GetProcessSP()->GetTarget().GetArchitecture();
+
+ // <addr> & 2 set is a fault if C extension is not used.
+ lldb_private::Flags arch_flags(arch.GetFlags());
+ if (!arch_flags.Test(lldb_private::ArchSpec::eRISCV_rvc) && (pc & 2))
+ return false;
+
+ // Make sure 64 bit addr_t only has lower 32 bits set on riscv32
+ llvm::Triple::ArchType machine = arch.GetMachine();
+ if (llvm::Triple::riscv32 == machine)
+ return (pc <= UINT32_MAX);
+
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp,
+ const lldb_private::ArchSpec &arch);
+
+ static llvm::StringRef GetPluginNameStatic() { return "sysv-riscv"; }
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+protected:
+ void AugmentRegisterInfo(
+ std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) override;
+
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+
+private:
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
+
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance
+ // instead.
+ bool m_is_rv64; // true if target is riscv64; false if target is riscv32
+};
+
+#endif // liblldb_ABISysV_riscv_h_
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
index 462317f17666..8c637b7671f6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
@@ -52,7 +52,7 @@ public:
// If we were to enforce 16-byte alignment, we also need to relax to 4-byte
// alignment for non-darwin i386 targets.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
- // Make sure the stack call frame addresses are are 4 byte aligned
+ // Make sure the stack call frame addresses are 4 byte aligned
if (cfa & (4ull - 1ull))
return false; // Not 4 byte aligned
if (cfa == 0)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
index 1b2b41ee8758..181ba4e7d877 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
@@ -8,7 +8,10 @@
#include "Plugins/Architecture/AArch64/ArchitectureAArch64.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
using namespace lldb_private;
using namespace lldb;
@@ -34,3 +37,88 @@ ArchitectureAArch64::Create(const ArchSpec &arch) {
}
return std::unique_ptr<Architecture>(new ArchitectureAArch64());
}
+
+static void
+UpdateARM64SVERegistersInfos(DynamicRegisterInfo::reg_collection_range regs,
+ uint64_t vg) {
+ // SVE Z register size is vg x 8 bytes.
+ uint32_t z_reg_byte_size = vg * 8;
+
+ // SVE vector length has changed, accordingly set size of Z, P and FFR
+ // registers. Also invalidate register offsets it will be recalculated
+ // after SVE register size update.
+ for (auto &reg : regs) {
+ if (reg.value_regs == nullptr) {
+ if (reg.name[0] == 'z' && isdigit(reg.name[1]))
+ reg.byte_size = z_reg_byte_size;
+ else if (reg.name[0] == 'p' && isdigit(reg.name[1]))
+ reg.byte_size = vg;
+ else if (strcmp(reg.name, "ffr") == 0)
+ reg.byte_size = vg;
+ }
+ reg.byte_offset = LLDB_INVALID_INDEX32;
+ }
+}
+
+static void
+UpdateARM64SMERegistersInfos(DynamicRegisterInfo::reg_collection_range regs,
+ uint64_t svg) {
+ for (auto &reg : regs) {
+ if (strcmp(reg.name, "za") == 0) {
+ // ZA is a register with size (svg*8) * (svg*8). A square essentially.
+ reg.byte_size = (svg * 8) * (svg * 8);
+ }
+ reg.byte_offset = LLDB_INVALID_INDEX32;
+ }
+}
+
+bool ArchitectureAArch64::ReconfigureRegisterInfo(DynamicRegisterInfo &reg_info,
+ DataExtractor &reg_data,
+ RegisterContext &reg_context
+
+) const {
+ // Once we start to reconfigure registers, we cannot read any of them.
+ // So we must read VG and SVG up front.
+
+ const uint64_t fail_value = LLDB_INVALID_ADDRESS;
+ std::optional<uint64_t> vg_reg_value;
+ const RegisterInfo *vg_reg_info = reg_info.GetRegisterInfo("vg");
+ if (vg_reg_info) {
+ uint32_t vg_reg_num = vg_reg_info->kinds[eRegisterKindLLDB];
+ uint64_t reg_value =
+ reg_context.ReadRegisterAsUnsigned(vg_reg_num, fail_value);
+ if (reg_value != fail_value && reg_value <= 32)
+ vg_reg_value = reg_value;
+ }
+
+ std::optional<uint64_t> svg_reg_value;
+ const RegisterInfo *svg_reg_info = reg_info.GetRegisterInfo("svg");
+ if (svg_reg_info) {
+ uint32_t svg_reg_num = svg_reg_info->kinds[eRegisterKindLLDB];
+ uint64_t reg_value =
+ reg_context.ReadRegisterAsUnsigned(svg_reg_num, fail_value);
+ if (reg_value != fail_value && reg_value <= 32)
+ svg_reg_value = reg_value;
+ }
+
+ if (!vg_reg_value && !svg_reg_value)
+ return false;
+
+ auto regs = reg_info.registers<DynamicRegisterInfo::reg_collection_range>();
+ if (vg_reg_value)
+ UpdateARM64SVERegistersInfos(regs, *vg_reg_value);
+ if (svg_reg_value)
+ UpdateARM64SMERegistersInfos(regs, *svg_reg_value);
+
+ // At this point if we have updated any registers, their offsets will all be
+ // invalid. If we did, we need to update them all.
+ reg_info.ConfigureOffsets();
+ // From here we are able to read registers again.
+
+ // Make a heap based buffer that is big enough to store all registers
+ reg_data.SetData(
+ std::make_shared<DataBufferHeap>(reg_info.GetRegisterDataByteSize(), 0));
+ reg_data.SetByteOrder(reg_context.GetByteOrder());
+
+ return true;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h
index da0b867fb1e9..ba409428c951 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h
@@ -28,6 +28,17 @@ public:
return &m_memory_tag_manager;
}
+ bool
+ RegisterWriteCausesReconfigure(const llvm::StringRef name) const override {
+ // lldb treats svg as read only, so only vg can be written. This results in
+ // the SVE registers changing size.
+ return name == "vg";
+ }
+
+ bool ReconfigureRegisterInfo(DynamicRegisterInfo &reg_info,
+ DataExtractor &reg_data,
+ RegisterContext &reg_context) const override;
+
private:
static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
ArchitectureAArch64() = default;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
index bb44675e842e..81c72122cb7e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
@@ -51,7 +51,7 @@ void ArchitectureArm::OverrideStopInfo(Thread &thread) const {
// stepping because the debugger stops regardless due to the BVR/BCR
// triggering a stop.
//
- // It also means we can set breakpoints on instructions inside an an if/then
+ // It also means we can set breakpoints on instructions inside an if/then
// block and correctly skip them if we use the BKPT instruction. The ARM and
// Thumb BKPT instructions are unconditional even when executed in a Thumb IT
// block.
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 09115cc670da..1628107170e7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -59,9 +60,11 @@ public:
uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len,
lldb::addr_t pc, llvm::MCInst &mc_inst) const;
- void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string,
- std::string &comments_string);
+ void PrintMCInst(llvm::MCInst &mc_inst, lldb::addr_t pc,
+ std::string &inst_string, std::string &comments_string);
void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style);
+ void SetUseColor(bool use_color);
+ bool GetUseColor() const;
bool CanBranch(llvm::MCInst &mc_inst) const;
bool HasDelaySlot(llvm::MCInst &mc_inst) const;
bool IsCall(llvm::MCInst &mc_inst) const;
@@ -75,7 +78,8 @@ private:
std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
std::unique_ptr<llvm::MCContext> &&context_up,
std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
- std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up);
+ std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up,
+ std::unique_ptr<llvm::MCInstrAnalysis> &&instr_analysis_up);
std::unique_ptr<llvm::MCInstrInfo> m_instr_info_up;
std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_up;
@@ -84,6 +88,7 @@ private:
std::unique_ptr<llvm::MCContext> m_context_up;
std::unique_ptr<llvm::MCDisassembler> m_disasm_up;
std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_up;
+ std::unique_ptr<llvm::MCInstrAnalysis> m_instr_analysis_up;
};
namespace x86 {
@@ -562,7 +567,9 @@ public:
if (m_opcode.GetData(data)) {
std::string out_string;
+ std::string markup_out_string;
std::string comment_string;
+ std::string markup_comment_string;
DisassemblerScope disasm(*this, exe_ctx);
if (disasm) {
@@ -604,7 +611,14 @@ public:
if (inst_size > 0) {
mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
- mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
+
+ const bool saved_use_color = mc_disasm_ptr->GetUseColor();
+ mc_disasm_ptr->SetUseColor(false);
+ mc_disasm_ptr->PrintMCInst(inst, pc, out_string, comment_string);
+ mc_disasm_ptr->SetUseColor(true);
+ mc_disasm_ptr->PrintMCInst(inst, pc, markup_out_string,
+ markup_comment_string);
+ mc_disasm_ptr->SetUseColor(saved_use_color);
if (!comment_string.empty()) {
AppendComment(comment_string);
@@ -669,6 +683,11 @@ public:
m_opcode_name = matches[1].str();
m_mnemonics = matches[2].str();
}
+ matches.clear();
+ if (s_regex.Execute(markup_out_string, &matches)) {
+ m_markup_opcode_name = matches[1].str();
+ m_markup_mnemonics = matches[2].str();
+ }
}
}
}
@@ -1287,11 +1306,17 @@ DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple, const char *cpu,
if (!instr_printer_up)
return Instance();
- return Instance(
- new MCDisasmInstance(std::move(instr_info_up), std::move(reg_info_up),
- std::move(subtarget_info_up), std::move(asm_info_up),
- std::move(context_up), std::move(disasm_up),
- std::move(instr_printer_up)));
+ instr_printer_up->setPrintBranchImmAsAddress(true);
+
+ // Not all targets may have registered createMCInstrAnalysis().
+ std::unique_ptr<llvm::MCInstrAnalysis> instr_analysis_up(
+ curr_target->createMCInstrAnalysis(instr_info_up.get()));
+
+ return Instance(new MCDisasmInstance(
+ std::move(instr_info_up), std::move(reg_info_up),
+ std::move(subtarget_info_up), std::move(asm_info_up),
+ std::move(context_up), std::move(disasm_up), std::move(instr_printer_up),
+ std::move(instr_analysis_up)));
}
DisassemblerLLVMC::MCDisasmInstance::MCDisasmInstance(
@@ -1301,13 +1326,15 @@ DisassemblerLLVMC::MCDisasmInstance::MCDisasmInstance(
std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
std::unique_ptr<llvm::MCContext> &&context_up,
std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
- std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up)
+ std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up,
+ std::unique_ptr<llvm::MCInstrAnalysis> &&instr_analysis_up)
: m_instr_info_up(std::move(instr_info_up)),
m_reg_info_up(std::move(reg_info_up)),
m_subtarget_info_up(std::move(subtarget_info_up)),
m_asm_info_up(std::move(asm_info_up)),
m_context_up(std::move(context_up)), m_disasm_up(std::move(disasm_up)),
- m_instr_printer_up(std::move(instr_printer_up)) {
+ m_instr_printer_up(std::move(instr_printer_up)),
+ m_instr_analysis_up(std::move(instr_analysis_up)) {
assert(m_instr_info_up && m_reg_info_up && m_subtarget_info_up &&
m_asm_info_up && m_context_up && m_disasm_up && m_instr_printer_up);
}
@@ -1328,15 +1355,17 @@ uint64_t DisassemblerLLVMC::MCDisasmInstance::GetMCInst(
}
void DisassemblerLLVMC::MCDisasmInstance::PrintMCInst(
- llvm::MCInst &mc_inst, std::string &inst_string,
+ llvm::MCInst &mc_inst, lldb::addr_t pc, std::string &inst_string,
std::string &comments_string) {
llvm::raw_string_ostream inst_stream(inst_string);
llvm::raw_string_ostream comments_stream(comments_string);
+ inst_stream.enable_colors(m_instr_printer_up->getUseColor());
m_instr_printer_up->setCommentStream(comments_stream);
- m_instr_printer_up->printInst(&mc_inst, 0, llvm::StringRef(),
+ m_instr_printer_up->printInst(&mc_inst, pc, llvm::StringRef(),
*m_subtarget_info_up, inst_stream);
m_instr_printer_up->setCommentStream(llvm::nulls());
+
comments_stream.flush();
static std::string g_newlines("\r\n");
@@ -1363,8 +1392,18 @@ void DisassemblerLLVMC::MCDisasmInstance::SetStyle(
}
}
+void DisassemblerLLVMC::MCDisasmInstance::SetUseColor(bool use_color) {
+ m_instr_printer_up->setUseColor(use_color);
+}
+
+bool DisassemblerLLVMC::MCDisasmInstance::GetUseColor() const {
+ return m_instr_printer_up->getUseColor();
+}
+
bool DisassemblerLLVMC::MCDisasmInstance::CanBranch(
llvm::MCInst &mc_inst) const {
+ if (m_instr_analysis_up)
+ return m_instr_analysis_up->mayAffectControlFlow(mc_inst, *m_reg_info_up);
return m_instr_info_up->get(mc_inst.getOpcode())
.mayAffectControlFlow(mc_inst, *m_reg_info_up);
}
@@ -1375,6 +1414,8 @@ bool DisassemblerLLVMC::MCDisasmInstance::HasDelaySlot(
}
bool DisassemblerLLVMC::MCDisasmInstance::IsCall(llvm::MCInst &mc_inst) const {
+ if (m_instr_analysis_up)
+ return m_instr_analysis_up->isCall(mc_inst);
return m_instr_info_up->get(mc_inst.getOpcode()).isCall();
}
@@ -1535,6 +1576,8 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
ArchSpec::eRISCV_float_abi_quad)
features_str += "+f,+d,+q,";
// FIXME: how do we detect features such as `+a`, `+m`?
+ // Turn them on by default now, since everyone seems to use them
+ features_str += "+a,+m,";
}
// We use m_disasm_up.get() to tell whether we are valid or not, so if this
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
new file mode 100644
index 000000000000..6d2e17d4eac6
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
@@ -0,0 +1,789 @@
+//===-- DynamicLoaderFreeBSDKernel.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/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/StreamFile.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/OperatingSystem.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+
+#include "DynamicLoaderFreeBSDKernel.h"
+#include <memory>
+#include <mutex>
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(DynamicLoaderFreeBSDKernel)
+
+void DynamicLoaderFreeBSDKernel::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInit);
+}
+
+void DynamicLoaderFreeBSDKernel::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+llvm::StringRef DynamicLoaderFreeBSDKernel::GetPluginDescriptionStatic() {
+ return "The Dynamic Loader Plugin For FreeBSD Kernel";
+}
+
+static bool is_kernel(Module *module) {
+ if (!module)
+ return false;
+
+ ObjectFile *objfile = module->GetObjectFile();
+ if (!objfile)
+ return false;
+ if (objfile->GetType() != ObjectFile::eTypeExecutable)
+ return false;
+ if (objfile->GetStrata() != ObjectFile::eStrataUnknown &&
+ objfile->GetStrata() != ObjectFile::eStrataKernel)
+ return false;
+
+ return true;
+}
+
+static bool is_kmod(Module *module) {
+ if (!module)
+ return false;
+ if (!module->GetObjectFile())
+ return false;
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile->GetType() != ObjectFile::eTypeObjectFile &&
+ objfile->GetType() != ObjectFile::eTypeSharedLibrary)
+ return false;
+
+ return true;
+}
+
+static bool is_reloc(Module *module) {
+ if (!module)
+ return false;
+ if (!module->GetObjectFile())
+ return false;
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile->GetType() != ObjectFile::eTypeObjectFile)
+ return false;
+
+ return true;
+}
+
+// Instantiate Function of the FreeBSD Kernel Dynamic Loader Plugin called when
+// Register the Plugin
+DynamicLoader *
+DynamicLoaderFreeBSDKernel::CreateInstance(lldb_private::Process *process,
+ bool force) {
+ // Check the environment when the plugin is not force loaded
+ Module *exec = process->GetTarget().GetExecutableModulePointer();
+ if (exec && !is_kernel(exec)) {
+ return nullptr;
+ }
+ if (!force) {
+ // Check if the target is kernel
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ if (!triple_ref.isOSFreeBSD()) {
+ return nullptr;
+ }
+ }
+
+ // At this point we have checked the target is a FreeBSD kernel and all we
+ // have to do is to find the kernel address
+ const addr_t kernel_address = FindFreeBSDKernel(process);
+
+ if (CheckForKernelImageAtAddress(process, kernel_address).IsValid())
+ return new DynamicLoaderFreeBSDKernel(process, kernel_address);
+
+ return nullptr;
+}
+
+addr_t
+DynamicLoaderFreeBSDKernel::FindFreeBSDKernel(lldb_private::Process *process) {
+ addr_t kernel_addr = process->GetImageInfoAddress();
+ if (kernel_addr == LLDB_INVALID_ADDRESS)
+ kernel_addr = FindKernelAtLoadAddress(process);
+ return kernel_addr;
+}
+
+// Get the kernel address if the kernel is not loaded with a slide
+addr_t DynamicLoaderFreeBSDKernel::FindKernelAtLoadAddress(
+ lldb_private::Process *process) {
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+
+ if (!is_kernel(exe_module))
+ return LLDB_INVALID_ADDRESS;
+
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+
+ if (!exe_objfile->GetBaseAddress().IsValid())
+ return LLDB_INVALID_ADDRESS;
+
+ if (CheckForKernelImageAtAddress(
+ process, exe_objfile->GetBaseAddress().GetFileAddress())
+ .IsValid())
+ return exe_objfile->GetBaseAddress().GetFileAddress();
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+// Read ELF header from memry and return
+bool DynamicLoaderFreeBSDKernel::ReadELFHeader(Process *process,
+ lldb::addr_t addr,
+ llvm::ELF::Elf32_Ehdr &header,
+ bool *read_error) {
+ Status error;
+ if (read_error)
+ *read_error = false;
+
+ if (process->ReadMemory(addr, &header, sizeof(header), error) !=
+ sizeof(header)) {
+ if (read_error)
+ *read_error = true;
+ return false;
+ }
+
+ if (!header.checkMagic())
+ return false;
+
+ return true;
+}
+
+// Check the correctness of Kernel and return UUID
+lldb_private::UUID DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress(
+ Process *process, lldb::addr_t addr, bool *read_error) {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+
+ if (addr == LLDB_INVALID_ADDRESS) {
+ if (read_error)
+ *read_error = true;
+ return UUID();
+ }
+
+ LLDB_LOGF(log,
+ "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
+ "looking for kernel binary at 0x%" PRIx64,
+ addr);
+
+ llvm::ELF::Elf32_Ehdr header;
+ if (!ReadELFHeader(process, addr, header)) {
+ *read_error = true;
+ return UUID();
+ }
+
+ // Check header type
+ if (header.e_type != llvm::ELF::ET_EXEC)
+ return UUID();
+
+ ModuleSP memory_module_sp =
+ process->ReadModuleFromMemory(FileSpec("temp_freebsd_kernel"), addr);
+
+ if (!memory_module_sp.get()) {
+ *read_error = true;
+ return UUID();
+ }
+
+ ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
+ if (exe_objfile == nullptr) {
+ LLDB_LOGF(log,
+ "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress "
+ "found a binary at 0x%" PRIx64
+ " but could not create an object file from memory",
+ addr);
+ return UUID();
+ }
+
+ // In here, I should check is_kernel for memory_module_sp
+ // However, the ReadModuleFromMemory reads wrong section so that this check
+ // will failed
+ ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine));
+
+ if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
+ process->GetTarget().SetArchitecture(kernel_arch);
+
+ std::string uuid_str;
+ if (memory_module_sp->GetUUID().IsValid()) {
+ uuid_str = "with UUID ";
+ uuid_str += memory_module_sp->GetUUID().GetAsString();
+ } else {
+ uuid_str = "and no LC_UUID found in load commands ";
+ }
+ LLDB_LOGF(log,
+ "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
+ "kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",
+ addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());
+
+ return memory_module_sp->GetUUID();
+}
+
+void DynamicLoaderFreeBSDKernel::DebuggerInit(
+ lldb_private::Debugger &debugger) {}
+
+DynamicLoaderFreeBSDKernel::DynamicLoaderFreeBSDKernel(Process *process,
+ addr_t kernel_address)
+ : DynamicLoader(process), m_process(process),
+ m_linker_file_list_struct_addr(LLDB_INVALID_ADDRESS),
+ m_linker_file_head_addr(LLDB_INVALID_ADDRESS),
+ m_kernel_load_address(kernel_address), m_mutex() {
+ process->SetCanRunCode(false);
+}
+
+DynamicLoaderFreeBSDKernel::~DynamicLoaderFreeBSDKernel() { Clear(true); }
+
+void DynamicLoaderFreeBSDKernel::Update() {
+ LoadKernelModules();
+ SetNotificationBreakPoint();
+}
+
+// Create in memory Module at the load address
+bool DynamicLoaderFreeBSDKernel::KModImageInfo::ReadMemoryModule(
+ lldb_private::Process *process) {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ if (m_memory_module_sp)
+ return true;
+ if (m_load_address == LLDB_INVALID_ADDRESS)
+ return false;
+
+ FileSpec file_spec(m_name);
+
+ ModuleSP memory_module_sp;
+
+ llvm::ELF::Elf32_Ehdr elf_eheader;
+ size_t size_to_read = 512;
+
+ if (ReadELFHeader(process, m_load_address, elf_eheader)) {
+ if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32) {
+ size_to_read = sizeof(llvm::ELF::Elf32_Ehdr) +
+ elf_eheader.e_phnum * elf_eheader.e_phentsize;
+ } else if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] ==
+ llvm::ELF::ELFCLASS64) {
+ llvm::ELF::Elf64_Ehdr elf_eheader;
+ Status error;
+ if (process->ReadMemory(m_load_address, &elf_eheader, sizeof(elf_eheader),
+ error) == sizeof(elf_eheader))
+ size_to_read = sizeof(llvm::ELF::Elf64_Ehdr) +
+ elf_eheader.e_phnum * elf_eheader.e_phentsize;
+ }
+ }
+
+ memory_module_sp =
+ process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read);
+
+ if (!memory_module_sp)
+ return false;
+
+ bool this_is_kernel = is_kernel(memory_module_sp.get());
+
+ if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
+ m_uuid = memory_module_sp->GetUUID();
+
+ m_memory_module_sp = memory_module_sp;
+ m_is_kernel = this_is_kernel;
+
+ // The kernel binary is from memory
+ if (this_is_kernel) {
+ LLDB_LOGF(log, "KextImageInfo::ReadMemoryModule read the kernel binary out "
+ "of memory");
+
+ if (memory_module_sp->GetArchitecture().IsValid())
+ process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
+ }
+
+ return true;
+}
+
+bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingMemoryModule(
+ lldb_private::Process *process) {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+
+ if (IsLoaded())
+ return true;
+
+ Target &target = process->GetTarget();
+
+ if (IsKernel() && m_uuid.IsValid()) {
+ Stream &s = target.GetDebugger().GetOutputStream();
+ s.Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str());
+ s.Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
+ }
+
+ // Test if the module is loaded into the taget,
+ // maybe the module is loaded manually by user by doing target module add
+ // So that we have to create the module manually
+ if (!m_module_sp) {
+ const ModuleList &target_images = target.GetImages();
+ m_module_sp = target_images.FindModule(m_uuid);
+
+ // Search in the file system
+ if (!m_module_sp) {
+ ModuleSpec module_spec(FileSpec(GetPath()), target.GetArchitecture());
+ if (IsKernel()) {
+ Status error;
+ if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error,
+ true)) {
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec()))
+ m_module_sp = std::make_shared<Module>(module_spec.GetFileSpec(),
+ target.GetArchitecture());
+ }
+ }
+
+ if (!m_module_sp)
+ m_module_sp = target.GetOrCreateModule(module_spec, true);
+ if (IsKernel() && !m_module_sp) {
+ Stream &s = target.GetDebugger().GetOutputStream();
+ s.Printf("WARNING: Unable to locate kernel binary on the debugger "
+ "system.\n");
+ }
+ }
+
+ if (m_module_sp) {
+ // If the file is not kernel or kmod, the target should be loaded once and
+ // don't reload again
+ if (!IsKernel() && !is_kmod(m_module_sp.get())) {
+ ModuleSP existing_module_sp = target.GetImages().FindModule(m_uuid);
+ if (existing_module_sp &&
+ existing_module_sp->IsLoadedInTarget(&target)) {
+ LLDB_LOGF(log,
+ "'%s' with UUID %s is not a kmod or kernel, and is "
+ "already registered in target, not loading.",
+ m_name.c_str(), m_uuid.GetAsString().c_str());
+ return true;
+ }
+ }
+ m_uuid = m_module_sp->GetUUID();
+
+ // or append to the images
+ target.GetImages().AppendIfNeeded(m_module_sp, false);
+ }
+ }
+
+ // If this file is relocatable kernel module(x86_64), adjust it's
+ // section(PT_LOAD segment) and return Because the kernel module's load
+ // address is the text section. lldb cannot create full memory module upon
+ // relocatable file So what we do is to set the load address only.
+ if (is_kmod(m_module_sp.get()) && is_reloc(m_module_sp.get())) {
+ m_stop_id = process->GetStopID();
+ bool changed = false;
+ m_module_sp->SetLoadAddress(target, m_load_address, true, changed);
+ return true;
+ }
+
+ if (m_module_sp)
+ ReadMemoryModule(process);
+
+ // Calculate the slides of in memory module
+ if (!m_memory_module_sp || !m_module_sp) {
+ m_module_sp.reset();
+ return false;
+ }
+
+ ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
+ ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
+
+ if (!ondisk_object_file || !memory_object_file)
+ m_module_sp.reset();
+
+ // Find the slide address
+ addr_t fixed_slide = LLDB_INVALID_ADDRESS;
+ if (ObjectFileELF *memory_objfile_elf =
+ llvm::dyn_cast<ObjectFileELF>(memory_object_file)) {
+ addr_t load_address = memory_object_file->GetBaseAddress().GetFileAddress();
+
+ if (load_address != LLDB_INVALID_ADDRESS &&
+ m_load_address != load_address) {
+ fixed_slide = m_load_address - load_address;
+ LLDB_LOGF(log,
+ "kmod %s in-memory LOAD vmaddr is not correct, using a "
+ "fixed slide of 0x%" PRIx64,
+ m_name.c_str(), fixed_slide);
+ }
+ }
+
+ SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
+ SectionList *memory_section_list = memory_object_file->GetSectionList();
+
+ if (memory_section_list && ondisk_object_file) {
+ const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
+ uint32_t num_load_sections = 0;
+
+ for (uint32_t section_idx = 0; section_idx < num_ondisk_sections;
+ ++section_idx) {
+ SectionSP on_disk_section_sp =
+ ondisk_section_list->GetSectionAtIndex(section_idx);
+
+ if (!on_disk_section_sp)
+ continue;
+ if (fixed_slide != LLDB_INVALID_ADDRESS) {
+ target.SetSectionLoadAddress(on_disk_section_sp,
+ on_disk_section_sp->GetFileAddress() +
+ fixed_slide);
+
+ } else {
+ const Section *memory_section =
+ memory_section_list
+ ->FindSectionByName(on_disk_section_sp->GetName())
+ .get();
+ if (memory_section) {
+ target.SetSectionLoadAddress(on_disk_section_sp,
+ memory_section->GetFileAddress());
+ ++num_load_sections;
+ }
+ }
+ }
+
+ if (num_load_sections)
+ m_stop_id = process->GetStopID();
+ else
+ m_module_sp.reset();
+ } else {
+ m_module_sp.reset();
+ }
+
+ if (IsLoaded() && m_module_sp && IsKernel()) {
+ Stream &s = target.GetDebugger().GetOutputStream();
+ ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
+ if (kernel_object_file) {
+ addr_t file_address =
+ kernel_object_file->GetBaseAddress().GetFileAddress();
+ if (m_load_address != LLDB_INVALID_ADDRESS &&
+ file_address != LLDB_INVALID_ADDRESS) {
+ s.Printf("Kernel slide 0x%" PRIx64 " in memory.\n",
+ m_load_address - file_address);
+ s.Printf("Loaded kernel file %s\n",
+ m_module_sp->GetFileSpec().GetPath().c_str());
+ }
+ }
+ s.Flush();
+ }
+
+ return IsLoaded();
+}
+
+// This function is work for kernel file, others it wil reset load address and
+// return false
+bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingFileAddress(
+ lldb_private::Process *process) {
+ if (IsLoaded())
+ return true;
+
+ if (m_module_sp) {
+ bool changed = false;
+ if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
+ m_stop_id = process->GetStopID();
+ }
+
+ return false;
+}
+
+// Get the head of found_list
+bool DynamicLoaderFreeBSDKernel::ReadKmodsListHeader() {
+ std::lock_guard<decltype(m_mutex)> guard(m_mutex);
+
+ if (m_linker_file_list_struct_addr.IsValid()) {
+ // Get tqh_first struct element from linker_files
+ Status error;
+ addr_t address = m_process->ReadPointerFromMemory(
+ m_linker_file_list_struct_addr.GetLoadAddress(&m_process->GetTarget()),
+ error);
+ if (address != LLDB_INVALID_ADDRESS && error.Success()) {
+ m_linker_file_head_addr = Address(address);
+ } else {
+ m_linker_file_list_struct_addr.Clear();
+ return false;
+ }
+
+ if (!m_linker_file_head_addr.IsValid() ||
+ m_linker_file_head_addr.GetFileAddress() == 0) {
+ m_linker_file_list_struct_addr.Clear();
+ return false;
+ }
+ }
+ return true;
+}
+
+// Parse Kmod info in found_list
+bool DynamicLoaderFreeBSDKernel::ParseKmods(Address linker_files_head_addr) {
+ std::lock_guard<decltype(m_mutex)> guard(m_mutex);
+ KModImageInfo::collection_type linker_files_list;
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+
+ if (!ReadAllKmods(linker_files_head_addr, linker_files_list))
+ return false;
+ LLDB_LOGF(
+ log,
+ "Kmod-changed breakpoint hit, there are %zu kernel modules currently.\n",
+ linker_files_list.size());
+
+ ModuleList &modules = m_process->GetTarget().GetImages();
+ ModuleList remove_modules;
+ ModuleList add_modules;
+
+ for (ModuleSP module : modules.Modules()) {
+ if (is_kernel(module.get()))
+ continue;
+ if (is_kmod(module.get()))
+ remove_modules.AppendIfNeeded(module);
+ }
+
+ m_process->GetTarget().ModulesDidUnload(remove_modules, false);
+
+ for (KModImageInfo &image_info : linker_files_list) {
+ if (m_kld_name_to_uuid.find(image_info.GetName()) !=
+ m_kld_name_to_uuid.end())
+ image_info.SetUUID(m_kld_name_to_uuid[image_info.GetName()]);
+ bool failed_to_load = false;
+ if (!image_info.LoadImageUsingMemoryModule(m_process)) {
+ image_info.LoadImageUsingFileAddress(m_process);
+ failed_to_load = true;
+ } else {
+ m_linker_files_list.push_back(image_info);
+ m_kld_name_to_uuid[image_info.GetName()] = image_info.GetUUID();
+ }
+
+ if (!failed_to_load)
+ add_modules.AppendIfNeeded(image_info.GetModule());
+ }
+ m_process->GetTarget().ModulesDidLoad(add_modules);
+ return true;
+}
+
+// Read all kmod from a given arrays of list
+bool DynamicLoaderFreeBSDKernel::ReadAllKmods(
+ Address linker_files_head_addr,
+ KModImageInfo::collection_type &kmods_list) {
+
+ // Get offset of next member and load address symbol
+ static ConstString kld_off_address_symbol_name("kld_off_address");
+ static ConstString kld_off_next_symbol_name("kld_off_next");
+ static ConstString kld_off_filename_symbol_name("kld_off_filename");
+ static ConstString kld_off_pathname_symbol_name("kld_off_pathname");
+ const Symbol *kld_off_address_symbol =
+ m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
+ kld_off_address_symbol_name, eSymbolTypeData);
+ const Symbol *kld_off_next_symbol =
+ m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
+ kld_off_next_symbol_name, eSymbolTypeData);
+ const Symbol *kld_off_filename_symbol =
+ m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
+ kld_off_filename_symbol_name, eSymbolTypeData);
+ const Symbol *kld_off_pathname_symbol =
+ m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
+ kld_off_pathname_symbol_name, eSymbolTypeData);
+
+ if (!kld_off_address_symbol || !kld_off_next_symbol ||
+ !kld_off_filename_symbol || !kld_off_pathname_symbol)
+ return false;
+
+ Status error;
+ const int32_t kld_off_address = m_process->ReadSignedIntegerFromMemory(
+ kld_off_address_symbol->GetAddress().GetLoadAddress(
+ &m_process->GetTarget()),
+ 4, 0, error);
+ if (error.Fail())
+ return false;
+ const int32_t kld_off_next = m_process->ReadSignedIntegerFromMemory(
+ kld_off_next_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget()),
+ 4, 0, error);
+ if (error.Fail())
+ return false;
+ const int32_t kld_off_filename = m_process->ReadSignedIntegerFromMemory(
+ kld_off_filename_symbol->GetAddress().GetLoadAddress(
+ &m_process->GetTarget()),
+ 4, 0, error);
+ if (error.Fail())
+ return false;
+
+ const int32_t kld_off_pathname = m_process->ReadSignedIntegerFromMemory(
+ kld_off_pathname_symbol->GetAddress().GetLoadAddress(
+ &m_process->GetTarget()),
+ 4, 0, error);
+ if (error.Fail())
+ return false;
+
+ // Parse KMods
+ addr_t kld_load_addr(LLDB_INVALID_ADDRESS);
+ char kld_filename[255];
+ char kld_pathname[255];
+ addr_t current_kld =
+ linker_files_head_addr.GetLoadAddress(&m_process->GetTarget());
+
+ while (current_kld != 0) {
+ addr_t kld_filename_addr =
+ m_process->ReadPointerFromMemory(current_kld + kld_off_filename, error);
+ if (error.Fail())
+ return false;
+ addr_t kld_pathname_addr =
+ m_process->ReadPointerFromMemory(current_kld + kld_off_pathname, error);
+ if (error.Fail())
+ return false;
+
+ m_process->ReadCStringFromMemory(kld_filename_addr, kld_filename,
+ sizeof(kld_filename), error);
+ if (error.Fail())
+ return false;
+ m_process->ReadCStringFromMemory(kld_pathname_addr, kld_pathname,
+ sizeof(kld_pathname), error);
+ if (error.Fail())
+ return false;
+ kld_load_addr =
+ m_process->ReadPointerFromMemory(current_kld + kld_off_address, error);
+ if (error.Fail())
+ return false;
+
+ kmods_list.emplace_back();
+ KModImageInfo &kmod_info = kmods_list.back();
+ kmod_info.SetName(kld_filename);
+ kmod_info.SetLoadAddress(kld_load_addr);
+ kmod_info.SetPath(kld_pathname);
+
+ current_kld =
+ m_process->ReadPointerFromMemory(current_kld + kld_off_next, error);
+ if (kmod_info.GetName() == "kernel")
+ kmods_list.pop_back();
+ if (error.Fail())
+ return false;
+ }
+
+ return true;
+}
+
+// Read all kmods
+void DynamicLoaderFreeBSDKernel::ReadAllKmods() {
+ std::lock_guard<decltype(m_mutex)> guard(m_mutex);
+
+ if (ReadKmodsListHeader()) {
+ if (m_linker_file_head_addr.IsValid()) {
+ if (!ParseKmods(m_linker_file_head_addr))
+ m_linker_files_list.clear();
+ }
+ }
+}
+
+// Load all Kernel Modules
+void DynamicLoaderFreeBSDKernel::LoadKernelModules() {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "
+ "Start loading Kernel Module");
+
+ // Initialize Kernel Image Information at the first time
+ if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
+ ModuleSP module_sp = m_process->GetTarget().GetExecutableModule();
+ if (is_kernel(module_sp.get())) {
+ m_kernel_image_info.SetModule(module_sp);
+ m_kernel_image_info.SetIsKernel(true);
+ }
+
+ // Set name for kernel
+ llvm::StringRef kernel_name("freebsd_kernel");
+ module_sp = m_kernel_image_info.GetModule();
+ if (module_sp.get() && module_sp->GetObjectFile() &&
+ !module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
+ kernel_name = module_sp->GetObjectFile()
+ ->GetFileSpec()
+ .GetFilename()
+ .GetStringRef();
+ m_kernel_image_info.SetName(kernel_name.data());
+
+ if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
+ m_kernel_image_info.SetLoadAddress(m_kernel_load_address);
+ }
+
+ // Build In memory Module
+ if (m_kernel_image_info.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+ // If the kernel is not loaded in the memory, use file to load
+ if (!m_kernel_image_info.LoadImageUsingMemoryModule(m_process))
+ m_kernel_image_info.LoadImageUsingFileAddress(m_process);
+ }
+ }
+
+ LoadOperatingSystemPlugin(false);
+
+ if (!m_kernel_image_info.IsLoaded() || !m_kernel_image_info.GetModule()) {
+ m_kernel_image_info.Clear();
+ return;
+ }
+
+ static ConstString modlist_symbol_name("linker_files");
+
+ const Symbol *symbol =
+ m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
+ modlist_symbol_name, lldb::eSymbolTypeData);
+
+ if (symbol) {
+ m_linker_file_list_struct_addr = symbol->GetAddress();
+ ReadAllKmods();
+ } else {
+ LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "
+ "cannot file modlist symbol");
+ }
+}
+
+// Update symbol when use kldload by setting callback function on kldload
+void DynamicLoaderFreeBSDKernel::SetNotificationBreakPoint() {}
+
+// Hook called when attach to a process
+void DynamicLoaderFreeBSDKernel::DidAttach() {
+ PrivateInitialize(m_process);
+ Update();
+}
+
+// Hook called after attach to a process
+void DynamicLoaderFreeBSDKernel::DidLaunch() {
+ PrivateInitialize(m_process);
+ Update();
+}
+
+// Clear all member except kernel address
+void DynamicLoaderFreeBSDKernel::Clear(bool clear_process) {
+ std::lock_guard<decltype(m_mutex)> guard(m_mutex);
+ if (clear_process)
+ m_process = nullptr;
+ m_linker_file_head_addr.Clear();
+ m_linker_file_list_struct_addr.Clear();
+ m_kernel_image_info.Clear();
+ m_linker_files_list.clear();
+}
+
+// Reinitialize class
+void DynamicLoaderFreeBSDKernel::PrivateInitialize(Process *process) {
+ Clear(true);
+ m_process = process;
+}
+
+ThreadPlanSP DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan(
+ lldb_private::Thread &thread, bool stop_others) {
+ Log *log = GetLog(LLDBLog::Step);
+ LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan is "
+ "not yet implemented.");
+ return {};
+}
+
+Status DynamicLoaderFreeBSDKernel::CanLoadImage() {
+ Status error("shared object cannot be loaded into kernel");
+ return error;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h
new file mode 100644
index 000000000000..d8656e9c49df
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h
@@ -0,0 +1,171 @@
+//===-- DynamicLoaderFreeBSDKernel.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_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H
+
+#include <mutex>
+#include <string>
+#include <vector>
+
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/UUID.h"
+#include "llvm/BinaryFormat/ELF.h"
+
+class DynamicLoaderFreeBSDKernel : public lldb_private::DynamicLoader {
+public:
+ DynamicLoaderFreeBSDKernel(lldb_private::Process *process,
+ lldb::addr_t kernel_addr);
+
+ ~DynamicLoaderFreeBSDKernel() override;
+
+ // Static Functions
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel"; }
+
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
+
+ static void DebuggerInit(lldb_private::Debugger &debugger);
+
+ static lldb::addr_t FindFreeBSDKernel(lldb_private::Process *process);
+
+ // Hooks for time point that after attach to some proccess
+ void DidAttach() override;
+
+ void DidLaunch() override;
+
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
+
+ lldb_private::Status CanLoadImage() override;
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+protected:
+ class KModImageInfo {
+ public:
+ KModImageInfo()
+ : m_module_sp(), m_memory_module_sp(), m_uuid(), m_name(), m_path() {}
+
+ void Clear() {
+ m_load_address = LLDB_INVALID_ADDRESS;
+ m_name.clear();
+ m_uuid.Clear();
+ m_module_sp.reset();
+ m_memory_module_sp.reset();
+ m_stop_id = UINT32_MAX;
+ m_path.clear();
+ }
+
+ void SetLoadAddress(lldb::addr_t load_address) {
+ m_load_address = load_address;
+ }
+
+ lldb::addr_t GetLoadAddress() const { return m_load_address; }
+
+ void SetUUID(const lldb_private::UUID uuid) { m_uuid = uuid; }
+
+ lldb_private::UUID GetUUID() const { return m_uuid; }
+
+ void SetName(const char *name) { m_name = name; }
+
+ std::string GetName() const { return m_name; }
+
+ void SetPath(const char *path) { m_path = path; }
+
+ std::string GetPath() const { return m_path; }
+
+ void SetModule(lldb::ModuleSP module) { m_module_sp = module; }
+
+ lldb::ModuleSP GetModule() { return m_module_sp; }
+
+ void SetIsKernel(bool is_kernel) { m_is_kernel = is_kernel; }
+
+ bool IsKernel() const { return m_is_kernel; };
+
+ void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }
+
+ uint32_t GetStopID() { return m_stop_id; }
+
+ bool IsLoaded() const { return m_stop_id != UINT32_MAX; };
+
+ bool ReadMemoryModule(lldb_private::Process *process);
+
+ bool LoadImageUsingMemoryModule(lldb_private::Process *process);
+
+ bool LoadImageUsingFileAddress(lldb_private::Process *process);
+
+ using collection_type = std::vector<KModImageInfo>;
+
+ private:
+ lldb::ModuleSP m_module_sp;
+ lldb::ModuleSP m_memory_module_sp;
+ lldb::addr_t m_load_address = LLDB_INVALID_ADDRESS;
+ lldb_private::UUID m_uuid;
+ bool m_is_kernel = false;
+ std::string m_name;
+ std::string m_path;
+ uint32_t m_stop_id = UINT32_MAX;
+ };
+
+ void PrivateInitialize(lldb_private::Process *process);
+
+ void Clear(bool clear_process);
+
+ void Update();
+
+ void LoadKernelModules();
+
+ void ReadAllKmods();
+
+ bool ReadAllKmods(lldb_private::Address linker_files_head_address,
+ KModImageInfo::collection_type &kmods_list);
+
+ bool ReadKmodsListHeader();
+
+ bool ParseKmods(lldb_private::Address linker_files_head_address);
+
+ void SetNotificationBreakPoint();
+
+ static lldb_private::UUID
+ CheckForKernelImageAtAddress(lldb_private::Process *process,
+ lldb::addr_t address,
+ bool *read_error = nullptr);
+
+ static lldb::addr_t FindKernelAtLoadAddress(lldb_private::Process *process);
+
+ static bool ReadELFHeader(lldb_private::Process *process,
+ lldb::addr_t address, llvm::ELF::Elf32_Ehdr &header,
+ bool *read_error = nullptr);
+
+ lldb_private::Process *m_process;
+ lldb_private::Address m_linker_file_list_struct_addr;
+ lldb_private::Address m_linker_file_head_addr;
+ lldb::addr_t m_kernel_load_address;
+ KModImageInfo m_kernel_image_info;
+ KModImageInfo::collection_type m_linker_files_list;
+ std::recursive_mutex m_mutex;
+ std::unordered_map<std::string, lldb_private::UUID> m_kld_name_to_uuid;
+
+private:
+ DynamicLoaderFreeBSDKernel(const DynamicLoaderFreeBSDKernel &) = delete;
+
+ const DynamicLoaderFreeBSDKernel &
+ operator=(const DynamicLoaderFreeBSDKernel &) = delete;
+};
+
+#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index f20167b46d27..1a9c4593b1b4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -25,6 +25,32 @@
using namespace lldb;
using namespace lldb_private;
+const char *DYLDRendezvous::StateToCStr(RendezvousState state) {
+ switch (state) {
+ case DYLDRendezvous::eConsistent:
+ return "eConsistent";
+ case DYLDRendezvous::eAdd:
+ return "eAdd";
+ case DYLDRendezvous::eDelete:
+ return "eDelete";
+ }
+ return "<invalid RendezvousState>";
+}
+
+const char *DYLDRendezvous::ActionToCStr(RendezvousAction action) {
+ switch (action) {
+ case DYLDRendezvous::RendezvousAction::eTakeSnapshot:
+ return "eTakeSnapshot";
+ case DYLDRendezvous::RendezvousAction::eAddModules:
+ return "eAddModules";
+ case DYLDRendezvous::RendezvousAction::eRemoveModules:
+ return "eRemoveModules";
+ case DYLDRendezvous::RendezvousAction::eNoAction:
+ return "eNoAction";
+ }
+ return "<invalid RendezvousAction>";
+}
+
DYLDRendezvous::DYLDRendezvous(Process *process)
: m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS),
m_executable_interpreter(false), m_current(), m_previous(),
@@ -129,6 +155,13 @@ void DYLDRendezvous::UpdateExecutablePath() {
}
}
+void DYLDRendezvous::Rendezvous::DumpToLog(Log *log, const char *label) {
+ LLDB_LOGF(log, "%s Rendezvous: version = %" PRIu64 ", map_addr = 0x%16.16"
+ PRIx64 ", brk = 0x%16.16" PRIx64 ", state = %" PRIu64
+ " (%s), ldbase = 0x%16.16" PRIx64, label ? label : "", version,
+ map_addr, brk, state, StateToCStr((RendezvousState)state), ldbase);
+}
+
bool DYLDRendezvous::Resolve() {
Log *log = GetLog(LLDBLog::DynamicLoader);
@@ -176,6 +209,9 @@ bool DYLDRendezvous::Resolve() {
m_previous = m_current;
m_current = info;
+ m_previous.DumpToLog(log, "m_previous");
+ m_current.DumpToLog(log, "m_current ");
+
if (m_current.map_addr == 0)
return false;
@@ -217,6 +253,75 @@ DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const {
break;
case eAdd:
+ // If the main executable or a shared library defines a publicly visible
+ // symbol named "_r_debug", then it will cause problems once the executable
+ // that contains the symbol is loaded into the process. The correct
+ // "_r_debug" structure is currently found by LLDB by looking through
+ // the .dynamic section in the main executable and finding the DT_DEBUG tag
+ // entry.
+ //
+ // An issue comes up if someone defines another publicly visible "_r_debug"
+ // struct in their program. Sample code looks like:
+ //
+ // #include <link.h>
+ // r_debug _r_debug;
+ //
+ // If code like this is in an executable or shared library, this creates a
+ // new "_r_debug" structure and it causes problems once the executable is
+ // loaded due to the way symbol lookups happen in linux: the shared library
+ // list from _r_debug.r_map will be searched for a symbol named "_r_debug"
+ // and the first match will be the new version that is used. The dynamic
+ // loader is always last in this list. So at some point the dynamic loader
+ // will start updating the copy of "_r_debug" that gets found first. The
+ // issue is that LLDB will only look at the copy that is pointed to by the
+ // DT_DEBUG entry, or the initial version from the ld.so binary.
+ //
+ // Steps that show the problem are:
+ //
+ // - LLDB finds the "_r_debug" structure via the DT_DEBUG entry in the
+ // .dynamic section and this points to the "_r_debug" in ld.so
+ // - ld.so uodates its copy of "_r_debug" with "state = eAdd" before it
+ // loads the dependent shared libraries for the main executable and
+ // any dependencies of all shared libraries from the executable's list
+ // and ld.so code calls the debugger notification function
+ // that LLDB has set a breakpoint on.
+ // - LLDB hits the breakpoint and the breakpoint has a callback function
+ // where we read the _r_debug.state (eAdd) state and we do nothing as the
+ // "eAdd" state indicates that the shared libraries are about to be added.
+ // - ld.so finishes loading the main executable and any dependent shared
+ // libraries and it will update the "_r_debug.state" member with a
+ // "eConsistent", but it now updates the "_r_debug" in the a.out program
+ // and it calls the debugger notification function.
+ // - lldb hits the notification breakpoint and checks the ld.so copy of
+ // "_r_debug.state" which still has a state of "eAdd", but LLDB needs to see a
+ // "eConsistent" state to trigger the shared libraries to get loaded into
+ // the debug session, but LLDB the ld.so _r_debug.state which still
+ // contains "eAdd" and doesn't do anyhing and library load is missed.
+ // The "_r_debug" in a.out has the state set correctly to "eConsistent"
+ // but LLDB is still looking at the "_r_debug" from ld.so.
+ //
+ // So if we detect two "eAdd" states in a row, we assume this is the issue
+ // and we now load shared libraries correctly and will emit a log message
+ // in the "log enable lldb dyld" log channel which states there might be
+ // multiple "_r_debug" structs causing problems.
+ //
+ // The correct solution is that no one should be adding a duplicate
+ // publicly visible "_r_debug" symbols to their binaries, but we have
+ // programs that are doing this already and since it can be done, we should
+ // be able to work with this and keep debug sessions working as expected.
+ //
+ // If a user includes the <link.h> file, they can just use the existing
+ // "_r_debug" structure as it is defined in this header file as "extern
+ // struct r_debug _r_debug;" and no local copies need to be made.
+ if (m_previous.state == eAdd) {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ LLDB_LOG(log, "DYLDRendezvous::GetAction() found two eAdd states in a "
+ "row, check process for multiple \"_r_debug\" symbols. "
+ "Returning eAddModules to ensure shared libraries get loaded "
+ "correctly");
+ return eAddModules;
+ }
+ return eNoAction;
case eDelete:
return eNoAction;
}
@@ -225,7 +330,9 @@ DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const {
}
bool DYLDRendezvous::UpdateSOEntriesFromRemote() {
- auto action = GetAction();
+ const auto action = GetAction();
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ LLDB_LOG(log, "{0} action = {1}", LLVM_PRETTY_FUNCTION, ActionToCStr(action));
if (action == eNoAction)
return false;
@@ -263,7 +370,10 @@ bool DYLDRendezvous::UpdateSOEntriesFromRemote() {
bool DYLDRendezvous::UpdateSOEntries() {
m_added_soentries.clear();
m_removed_soentries.clear();
- switch (GetAction()) {
+ const auto action = GetAction();
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ LLDB_LOG(log, "{0} action = {1}", LLVM_PRETTY_FUNCTION, ActionToCStr(action));
+ switch (action) {
case eTakeSnapshot:
m_soentries.clear();
return TakeSnapshot(m_soentries);
@@ -372,7 +482,7 @@ bool DYLDRendezvous::RemoveSOEntriesFromRemote(
// Only add shared libraries and not the executable.
if (!SOEntryIsMainExecutable(entry)) {
- auto pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ auto pos = llvm::find(m_soentries, entry);
if (pos == m_soentries.end())
return false;
@@ -439,6 +549,7 @@ bool DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry) {
switch (triple.getOS()) {
case llvm::Triple::FreeBSD:
case llvm::Triple::NetBSD:
+ case llvm::Triple::OpenBSD:
return entry.file_spec == m_exe_file_spec;
case llvm::Triple::Linux:
if (triple.isAndroid())
@@ -600,16 +711,19 @@ bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field,
target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
eSymbolTypeAny, list);
if (list.IsEmpty())
- return false;
+ return false;
Address address = list[0].symbol->GetAddress();
- addr_t addr = address.GetLoadAddress(&target);
- if (addr == LLDB_INVALID_ADDRESS)
- return false;
+ address.SetOffset(address.GetOffset() + field * sizeof(uint32_t));
+ // Read from target memory as this allows us to try process memory and
+ // fallback to reading from read only sections from the object files. Here we
+ // are reading read only data from libpthread.so to find data in the thread
+ // specific area for the data we want and this won't be saved into process
+ // memory due to it being read only.
Status error;
- value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(
- addr + field * sizeof(uint32_t), sizeof(uint32_t), 0, error);
+ value =
+ target.ReadUnsignedIntegerFromMemory(address, sizeof(uint32_t), 0, error);
if (error.Fail())
return false;
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 fc1dd6921455..b8bdf78fbdfa 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
@@ -21,6 +21,7 @@
using lldb_private::LoadedModuleInfoList;
namespace lldb_private {
+class Log;
class Process;
}
@@ -28,9 +29,81 @@ class Process;
/// Interface to the runtime linker.
///
/// A structure is present in a processes memory space which is updated by the
-/// runtime liker each time a module is loaded or unloaded. This class
+/// dynamic linker each time a module is loaded or unloaded. This class
/// provides an interface to this structure and maintains a consistent
/// snapshot of the currently loaded modules.
+///
+/// In the dynamic loader sources, this structure has a type of "r_debug" and
+/// the name of the structure us "_r_debug". The structure looks like:
+///
+/// struct r_debug {
+/// // Version number for this protocol.
+/// int r_version;
+/// // Head of the chain of loaded objects.
+/// struct link_map *r_map;
+/// // The address the debugger should set a breakpoint at in order to get
+/// // notified when shared libraries are added or removed
+/// uintptr_t r_brk;
+/// // This state value describes the mapping change taking place when the
+/// // 'r_brk' address is called.
+/// enum {
+/// RT_CONSISTENT, // Mapping change is complete.
+/// RT_ADD, // Beginning to add a new object.
+/// RT_DELETE, // Beginning to remove an object mapping.
+/// } r_state;
+/// // Base address the linker is loaded at.
+/// uintptr_t r_ldbase;
+/// };
+///
+/// The dynamic linker then defines a global variable using this type named
+/// "_r_debug":
+///
+/// r_debug _r_debug;
+///
+/// The DYLDRendezvous class defines a local version of this structure named
+/// DYLDRendezvous::Rendezvous. See the definition inside the class definition
+/// for DYLDRendezvous.
+///
+/// This structure can be located by looking through the .dynamic section in
+/// the main executable and finding the DT_DEBUG tag entry. This value starts
+/// out with a value of zero when the program first is initially loaded, but
+/// the address of the "_r_debug" structure from ld.so is filled in by the
+/// dynamic loader during program initialization code in ld.so prior to loading
+/// or unloading and shared libraries.
+///
+/// The dynamic loader will update this structure as shared libraries are
+/// loaded and will call a specific function that LLDB knows to set a
+/// breakpoint on (from _r_debug.r_brk) so LLDB will find out when shared
+/// libraries are loaded or unloaded. Each time this breakpoint is hit, LLDB
+/// looks at the contents of this structure and the contents tell LLDB what
+/// needs to be done.
+///
+/// Currently we expect the "state" in this structure to change as things
+/// happen.
+///
+/// When any shared libraries are loaded the following happens:
+/// - _r_debug.r_map is updated with the new shared libraries. This is a
+/// doubly linked list of "link_map *" entries.
+/// - _r_debug.r_state is set to RT_ADD and the debugger notification
+/// function is called notifying the debugger that shared libraries are
+/// about to be added, but are not yet ready for use.
+/// - Once the the shared libraries are fully loaded, _r_debug.r_state is set
+/// to RT_CONSISTENT and the debugger notification function is called again
+/// notifying the debugger that shared libraries are ready for use.
+/// DYLDRendezvous must remember that the previous state was RT_ADD when it
+/// receives a RT_CONSISTENT in order to know to add libraries
+///
+/// When any shared libraries are unloaded the following happens:
+/// - _r_debug.r_map is updated and the unloaded libraries are removed.
+/// - _r_debug.r_state is set to RT_DELETE and the debugger notification
+/// function is called notifying the debugger that shared libraries are
+/// about to be removed.
+/// - Once the the shared libraries are removed _r_debug.r_state is set to
+/// RT_CONSISTENT and the debugger notification function is called again
+/// notifying the debugger that shared libraries have been removed.
+/// DYLDRendezvous must remember that the previous state was RT_DELETE when
+/// it receives a RT_CONSISTENT in order to know to remove libraries
+///
class DYLDRendezvous {
// This structure is used to hold the contents of the debug rendezvous
@@ -45,6 +118,8 @@ class DYLDRendezvous {
lldb::addr_t ldbase = 0;
Rendezvous() = default;
+
+ void DumpToLog(lldb_private::Log *log, const char *label);
};
/// Locates the address of the rendezvous structure. It updates
@@ -126,8 +201,15 @@ public:
/// Constants describing the state of the rendezvous.
///
+ /// These values are defined to match the r_debug.r_state enum from the
+ /// actual dynamic loader sources.
+ ///
/// \see GetState().
- enum RendezvousState { eConsistent, eAdd, eDelete };
+ enum RendezvousState {
+ eConsistent, // RT_CONSISTENT
+ eAdd, // RT_ADD
+ eDelete // RT_DELETE
+ };
/// Structure representing the shared objects currently loaded into the
/// inferior process.
@@ -276,6 +358,9 @@ protected:
eRemoveModules
};
+ static const char *StateToCStr(RendezvousState state);
+ static const char *ActionToCStr(RendezvousAction action);
+
/// Returns the current action to be taken given the current and previous
/// state
RendezvousAction GetAction() const;
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index b4b38a88e1b9..9baf86da4dc7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -53,7 +53,8 @@ DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process,
process->GetTarget().GetArchitecture().GetTriple();
if (triple_ref.getOS() == llvm::Triple::FreeBSD ||
triple_ref.getOS() == llvm::Triple::Linux ||
- triple_ref.getOS() == llvm::Triple::NetBSD)
+ triple_ref.getOS() == llvm::Triple::NetBSD ||
+ triple_ref.getOS() == llvm::Triple::OpenBSD)
create = true;
}
@@ -337,29 +338,20 @@ bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
};
ModuleSP interpreter = LoadInterpreterModule();
- if (!interpreter) {
- FileSpecList containingModules;
+ FileSpecList containingModules;
+ if (interpreter)
+ containingModules.Append(interpreter->GetFileSpec());
+ else
containingModules.Append(
m_process->GetTarget().GetExecutableModulePointer()->GetFileSpec());
- dyld_break = target.CreateBreakpoint(
- &containingModules, /*containingSourceFiles=*/nullptr,
- DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
- /*m_offset=*/0,
- /*skip_prologue=*/eLazyBoolNo,
- /*internal=*/true,
- /*request_hardware=*/false);
- } else {
- FileSpecList containingModules;
- containingModules.Append(interpreter->GetFileSpec());
- dyld_break = target.CreateBreakpoint(
- &containingModules, /*containingSourceFiles=*/nullptr,
- DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
- /*m_offset=*/0,
- /*skip_prologue=*/eLazyBoolNo,
- /*internal=*/true,
- /*request_hardware=*/false);
- }
+ dyld_break = target.CreateBreakpoint(
+ &containingModules, /*containingSourceFiles=*/nullptr,
+ DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
+ /*m_offset=*/0,
+ /*skip_prologue=*/eLazyBoolNo,
+ /*internal=*/true,
+ /*request_hardware=*/false);
}
if (dyld_break->GetNumResolvedLocations() != 1) {
@@ -420,6 +412,11 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
if (!m_rendezvous.Resolve())
return;
+ // The rendezvous class doesn't enumerate the main module, so track that
+ // ourselves here.
+ ModuleSP executable = GetTargetExecutable();
+ m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
+
DYLDRendezvous::iterator I;
DYLDRendezvous::iterator E;
@@ -441,6 +438,14 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
m_initial_modules_added = true;
}
for (; I != E; ++I) {
+ // Don't load a duplicate copy of ld.so if we have already loaded it
+ // earlier in LoadInterpreterModule. If we instead loaded then unloaded it
+ // later, the section information for ld.so would be removed. That
+ // information is required for placing breakpoints on Arm/Thumb systems.
+ if ((m_interpreter_module.lock() != nullptr) &&
+ (I->base_addr == m_interpreter_base))
+ continue;
+
ModuleSP module_sp =
LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
if (!module_sp.get())
@@ -454,15 +459,6 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
} else if (module_sp == interpreter_sp) {
// Module already loaded.
continue;
- } else {
- // If this is a duplicate instance of ld.so, unload it. We may end
- // up with it if we load it via a different path than before
- // (symlink vs real path).
- // TODO: remove this once we either fix library matching or avoid
- // loading the interpreter when setting the rendezvous breakpoint.
- UnloadSections(module_sp);
- loaded_modules.Remove(module_sp);
- continue;
}
}
@@ -727,41 +723,66 @@ lldb::addr_t
DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
const lldb::ThreadSP thread,
lldb::addr_t tls_file_addr) {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
auto it = m_loaded_modules.find(module_sp);
- if (it == m_loaded_modules.end())
+ if (it == m_loaded_modules.end()) {
+ LLDB_LOGF(
+ log, "GetThreadLocalData error: module(%s) not found in loaded modules",
+ module_sp->GetObjectName().AsCString());
return LLDB_INVALID_ADDRESS;
+ }
addr_t link_map = it->second;
- if (link_map == LLDB_INVALID_ADDRESS)
+ if (link_map == LLDB_INVALID_ADDRESS || link_map == 0) {
+ LLDB_LOGF(log,
+ "GetThreadLocalData error: invalid link map address=0x%" PRIx64,
+ link_map);
return LLDB_INVALID_ADDRESS;
+ }
const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
- if (!metadata.valid)
+ if (!metadata.valid) {
+ LLDB_LOGF(log,
+ "GetThreadLocalData error: fail to read thread info metadata");
return LLDB_INVALID_ADDRESS;
+ }
+
+ LLDB_LOGF(log,
+ "GetThreadLocalData info: link_map=0x%" PRIx64
+ ", thread info metadata: "
+ "modid_offset=0x%" PRIx32 ", dtv_offset=0x%" PRIx32
+ ", tls_offset=0x%" PRIx32 ", dtv_slot_size=%" PRIx32 "\n",
+ link_map, metadata.modid_offset, metadata.dtv_offset,
+ metadata.tls_offset, metadata.dtv_slot_size);
// Get the thread pointer.
addr_t tp = thread->GetThreadPointer();
- if (tp == LLDB_INVALID_ADDRESS)
+ if (tp == LLDB_INVALID_ADDRESS) {
+ LLDB_LOGF(log, "GetThreadLocalData error: fail to read thread pointer");
return LLDB_INVALID_ADDRESS;
+ }
// Find the module's modid.
int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
int64_t modid = ReadUnsignedIntWithSizeInBytes(
link_map + metadata.modid_offset, modid_size);
- if (modid == -1)
+ if (modid == -1) {
+ LLDB_LOGF(log, "GetThreadLocalData error: fail to read modid");
return LLDB_INVALID_ADDRESS;
+ }
// Lookup the DTV structure for this thread.
addr_t dtv_ptr = tp + metadata.dtv_offset;
addr_t dtv = ReadPointer(dtv_ptr);
- if (dtv == LLDB_INVALID_ADDRESS)
+ if (dtv == LLDB_INVALID_ADDRESS) {
+ LLDB_LOGF(log, "GetThreadLocalData error: fail to read dtv");
return LLDB_INVALID_ADDRESS;
+ }
// Find the TLS block for this module.
addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
- Log *log = GetLog(LLDBLog::DynamicLoader);
LLDB_LOGF(log,
"DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
"module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
@@ -769,9 +790,10 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
module_sp->GetObjectName().AsCString(""), link_map, tp,
(int64_t)modid, tls_block);
- if (tls_block == LLDB_INVALID_ADDRESS)
+ if (tls_block == LLDB_INVALID_ADDRESS) {
+ LLDB_LOGF(log, "GetThreadLocalData error: fail to read tls_block");
return LLDB_INVALID_ADDRESS;
- else
+ } else
return tls_block + tls_file_addr;
}
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 2826b102625f..5d109feb3d39 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -902,7 +902,6 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
// We want that 'to' is actually complete after this function so let's
// tell the ASTImporter that 'to' was imported from 'from'.
MapImported(from, to);
- ASTImporter::Imported(from, to);
Log *log = GetLog(LLDBLog::Expressions);
@@ -1028,7 +1027,7 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
// Some decls shouldn't be tracked here because they were not created by
// copying 'from' to 'to'. Just exit early for those.
if (m_decls_to_ignore.count(to))
- return clang::ASTImporter::Imported(from, to);
+ return;
// Transfer module ownership information.
auto *from_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
@@ -1081,12 +1080,6 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID)
to_context_md->setOrigin(to, origin);
- ImporterDelegateSP direct_completer =
- m_main.GetDelegate(&to->getASTContext(), origin.ctx);
-
- 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 "
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 5d7e1252038d..79dd306f7627 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -201,19 +201,17 @@ TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
LLDB_LOG(log, " CTD Searching namespace {0} in module {1}",
item.second.GetName(), item.first->GetFileSpec().GetFilename());
- TypeList types;
-
ConstString name(decl->getName());
- item.first->FindTypesInNamespace(name, item.second, UINT32_MAX, types);
-
- for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
-
- if (!type)
- continue;
+ // Create a type matcher using the CompilerDeclContext for the namespace
+ // as the context (item.second) and search for the name inside of this
+ // context.
+ TypeQuery query(item.second, name);
+ TypeResults results;
+ item.first->FindTypes(query, results);
- CompilerType clang_type(type->GetFullCompilerType());
+ for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types()) {
+ CompilerType clang_type(type_sp->GetFullCompilerType());
if (!ClangUtil::IsClangType(clang_type))
continue;
@@ -233,24 +231,15 @@ TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
}
}
} else {
- TypeList types;
-
- ConstString name(decl->getName());
-
const ModuleList &module_list = m_target->GetImages();
+ // Create a type matcher using a CompilerDecl. Each TypeSystem class knows
+ // how to fill out a CompilerContext array using a CompilerDecl.
+ TypeQuery query(CompilerDecl(m_clang_ast_context, (void *)decl));
+ TypeResults results;
+ module_list.FindTypes(nullptr, query, results);
+ for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types()) {
- bool exact_match = false;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
- searched_symbol_files, types);
-
- for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
-
- if (!type)
- continue;
-
- CompilerType clang_type(type->GetFullCompilerType());
+ CompilerType clang_type(type_sp->GetFullCompilerType());
if (!ClangUtil::IsClangType(clang_type))
continue;
@@ -263,13 +252,6 @@ TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
TagDecl *candidate_tag_decl = const_cast<TagDecl *>(tag_type->getDecl());
- // We have found a type by basename and we need to make sure the decl
- // contexts are the same before we can try to complete this type with
- // another
- if (!TypeSystemClang::DeclsAreEquivalent(const_cast<TagDecl *>(decl),
- candidate_tag_decl))
- continue;
-
if (TypeSystemClang::GetCompleteDecl(&candidate_tag_decl->getASTContext(),
candidate_tag_decl))
return candidate_tag_decl;
@@ -589,8 +571,8 @@ bool ClangASTSource::IgnoreName(const ConstString name,
// The ClangASTSource is not responsible for finding $-names.
return name_string_ref.empty() ||
- (ignore_all_dollar_names && name_string_ref.startswith("$")) ||
- name_string_ref.startswith("_$");
+ (ignore_all_dollar_names && name_string_ref.starts_with("$")) ||
+ name_string_ref.starts_with("_$");
}
void ClangASTSource::FindExternalVisibleDecls(
@@ -614,41 +596,40 @@ void ClangASTSource::FindExternalVisibleDecls(
if (context.m_found_type)
return;
- TypeList types;
- const bool exact_match = true;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- if (module_sp && namespace_decl)
- module_sp->FindTypesInNamespace(name, namespace_decl, 1, types);
- else {
- m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
- searched_symbol_files, types);
+ lldb::TypeSP type_sp;
+ TypeResults results;
+ if (module_sp && namespace_decl) {
+ // Match the name in the specified decl context.
+ TypeQuery query(namespace_decl, name, TypeQueryOptions::e_find_one);
+ module_sp->FindTypes(query, results);
+ type_sp = results.GetFirstType();
+ } else {
+ // Match the exact name of the type at the root level.
+ TypeQuery query(name.GetStringRef(), TypeQueryOptions::e_exact_match |
+ TypeQueryOptions::e_find_one);
+ m_target->GetImages().FindTypes(nullptr, query, results);
+ type_sp = results.GetFirstType();
}
- if (size_t num_types = types.GetSize()) {
- for (size_t ti = 0; ti < num_types; ++ti) {
- lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
-
- if (log) {
- const char *name_string = type_sp->GetName().GetCString();
-
- LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name,
- (name_string ? name_string : "<anonymous>"));
- }
+ if (type_sp) {
+ if (log) {
+ const char *name_string = type_sp->GetName().GetCString();
- CompilerType full_type = type_sp->GetFullCompilerType();
+ LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name,
+ (name_string ? name_string : "<anonymous>"));
+ }
- CompilerType copied_clang_type(GuardedCopyType(full_type));
+ CompilerType full_type = type_sp->GetFullCompilerType();
- if (!copied_clang_type) {
- LLDB_LOG(log, " CAS::FEVD - Couldn't export a type");
+ CompilerType copied_clang_type(GuardedCopyType(full_type));
- continue;
- }
+ if (!copied_clang_type) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type");
+ } else {
context.AddTypeDecl(copied_clang_type);
context.m_found_type = true;
- break;
}
}
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 6fbc0bb22f82..2d306b42760b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1369,7 +1369,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (!namespace_decl)
SearchPersistenDecls(context, name);
- if (name.GetStringRef().startswith("$") && !namespace_decl) {
+ if (name.GetStringRef().starts_with("$") && !namespace_decl) {
if (name == "$__lldb_class") {
LookUpLldbClass(context);
return;
@@ -1385,7 +1385,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
// any other $__lldb names should be weeded out now
- if (name.GetStringRef().startswith("$__lldb"))
+ if (name.GetStringRef().starts_with("$__lldb"))
return;
// No ParserVars means we can't do register or variable lookup.
@@ -1400,7 +1400,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
return;
}
- assert(name.GetStringRef().startswith("$"));
+ assert(name.GetStringRef().starts_with("$"));
llvm::StringRef reg_name = name.GetStringRef().substr(1);
if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
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 9430ab5b0464..d8d519693f10 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -53,7 +53,7 @@ class ClangPersistentVariables;
/// struct so that it can be passed to the JITted version of the IR.
///
/// Fourth and finally, it "dematerializes" the struct after the JITted code
-/// has has executed, placing the new values back where it found the old ones.
+/// has executed, placing the new values back where it found the old ones.
class ClangExpressionDeclMap : public ClangASTSource {
public:
/// Constructor
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 f3d6ea26b30d..574d661e2a21 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -71,7 +71,6 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/File.h"
@@ -576,6 +575,7 @@ ClangExpressionParser::ClangExpressionParser(
lang_opts.GNUMode = true;
lang_opts.GNUKeywords = true;
lang_opts.CPlusPlus11 = true;
+ lang_opts.BuiltinHeadersInSystemModules = true;
// The Darwin libc expects this macro to be set.
lang_opts.GNUCVersion = 40201;
@@ -834,13 +834,13 @@ public:
case CodeCompletionResult::RK_Declaration:
return !(
Result.Declaration->getIdentifier() &&
- Result.Declaration->getIdentifier()->getName().startswith(Filter));
+ Result.Declaration->getIdentifier()->getName().starts_with(Filter));
case CodeCompletionResult::RK_Keyword:
- return !StringRef(Result.Keyword).startswith(Filter);
+ return !StringRef(Result.Keyword).starts_with(Filter);
case CodeCompletionResult::RK_Macro:
- return !Result.Macro->getName().startswith(Filter);
+ return !Result.Macro->getName().starts_with(Filter);
case CodeCompletionResult::RK_Pattern:
- return !StringRef(Result.Pattern->getAsString()).startswith(Filter);
+ return !StringRef(Result.Pattern->getAsString()).starts_with(Filter);
}
// If we trigger this assert or the above switch yields a warning, then
// CodeCompletionResult has been enhanced with more kinds of completion
@@ -904,7 +904,7 @@ private:
}
// We also filter some internal lldb identifiers here. The user
// shouldn't see these.
- if (llvm::StringRef(ToInsert).startswith("$__lldb_"))
+ if (llvm::StringRef(ToInsert).starts_with("$__lldb_"))
return std::nullopt;
if (ToInsert.empty())
return std::nullopt;
@@ -1078,13 +1078,14 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
// While parsing the Sema will call this consumer with the provided
// completion suggestions.
if (completion_consumer) {
- auto main_file = source_mgr.getFileEntryForID(source_mgr.getMainFileID());
+ auto main_file =
+ source_mgr.getFileEntryRefForID(source_mgr.getMainFileID());
auto &PP = m_compiler->getPreprocessor();
// Lines and columns start at 1 in Clang, but code completion positions are
// indexed from 0, so we need to add 1 to the line and column here.
++completion_line;
++completion_column;
- PP.SetCodeCompletionPoint(main_file, completion_line, completion_column);
+ PP.SetCodeCompletionPoint(*main_file, completion_line, completion_column);
}
ASTConsumer *ast_transformer =
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 74c1212791be..68bdd96e8adb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -27,7 +27,6 @@
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
@@ -873,7 +872,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
}
lldb::addr_t ClangUserExpression::GetCppObjectPointer(
- lldb::StackFrameSP frame_sp, ConstString &object_name, Status &err) {
+ lldb::StackFrameSP frame_sp, llvm::StringRef object_name, Status &err) {
auto valobj_sp =
GetObjectPointerValueObject(std::move(frame_sp), object_name, err);
@@ -890,9 +889,9 @@ lldb::addr_t ClangUserExpression::GetCppObjectPointer(
lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
if (ret == LLDB_INVALID_ADDRESS) {
- err.SetErrorStringWithFormat(
- "Couldn't load '%s' because its value couldn't be evaluated",
- object_name.AsCString());
+ err.SetErrorStringWithFormatv(
+ "Couldn't load '{0}' because its value couldn't be evaluated",
+ object_name);
return LLDB_INVALID_ADDRESS;
}
@@ -911,19 +910,18 @@ bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
if (!frame_sp)
return true;
- ConstString object_name;
-
- if (m_in_cplusplus_method) {
- object_name.SetCString("this");
- } else if (m_in_objectivec_method) {
- object_name.SetCString("self");
- } else {
+ if (!m_in_cplusplus_method && !m_in_objectivec_method) {
diagnostic_manager.PutString(
eDiagnosticSeverityError,
"need object pointer but don't know the language");
return false;
}
+ static constexpr llvm::StringLiteral g_cplusplus_object_name("this");
+ static constexpr llvm::StringLiteral g_objc_object_name("self");
+ llvm::StringRef object_name =
+ m_in_cplusplus_method ? g_cplusplus_object_name : g_objc_object_name;
+
Status object_ptr_error;
if (m_ctx_obj) {
@@ -943,14 +941,14 @@ bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
}
if (!object_ptr_error.Success()) {
- exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf(
- "warning: `%s' is not accessible (substituting 0). %s\n",
- object_name.AsCString(), object_ptr_error.AsCString());
+ exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Format(
+ "warning: `{0}' is not accessible (substituting 0). {1}\n",
+ object_name, object_ptr_error.AsCString());
object_ptr = 0;
}
if (m_in_objectivec_method) {
- ConstString cmd_name("_cmd");
+ static constexpr llvm::StringLiteral cmd_name("_cmd");
cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 0fbeff7f6143..7a8c095f6118 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -204,7 +204,7 @@ private:
bool for_completion);
lldb::addr_t GetCppObjectPointer(lldb::StackFrameSP frame,
- ConstString &object_name, Status &err);
+ llvm::StringRef object_name, Status &err);
/// Defines how the current expression should be wrapped.
ClangExpressionSourceCode::WrapKind GetWrapKind() const;
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 371605d427ad..56d6cf19ee4c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -17,7 +17,6 @@
#include "lldb/Core/Module.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/ExecutionContext.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index 847dab6592b8..62443d1290dc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -72,7 +72,7 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f,
// path. Ignore subdirectories such as /c++/v1/experimental as those don't
// need to be specified in the header search.
if (libcpp_regex.match(f.GetPath()) &&
- parent_path(posix_dir, Style::posix).endswith("c++")) {
+ parent_path(posix_dir, Style::posix).ends_with("c++")) {
if (!m_std_inc.TrySet(posix_dir))
return false;
if (triple.str().empty())
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index cd7d1ff6148b..bc0f5993aad0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -273,7 +273,7 @@ protected:
PointerType *GetI8PtrTy() {
if (!m_i8ptr_ty)
- m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
+ m_i8ptr_ty = llvm::PointerType::getUnqual(m_module.getContext());
return m_i8ptr_ty;
}
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 1b7e86bb187f..597873af8b2a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -154,9 +154,10 @@ clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
/// Returns true iff the mangled symbol is for a static guard variable.
static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol,
bool check_ms_abi = true) {
- bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable
+ bool result =
+ mangled_symbol.starts_with("_ZGV"); // Itanium ABI guard variable
if (check_ms_abi)
- result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI
+ result |= mangled_symbol.ends_with("@4IA"); // Microsoft ABI
return result;
}
@@ -404,7 +405,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
Type *ns_str_ty = ns_str->getType();
- Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
+ Type *i8_ptr_ty = PointerType::getUnqual(m_module->getContext());
Type *i32_ty = Type::getInt32Ty(m_module->getContext());
Type *i8_ty = Type::getInt8Ty(m_module->getContext());
@@ -720,8 +721,9 @@ bool IRForTarget::RewriteObjCConstStrings() {
static bool IsObjCSelectorRef(Value *value) {
GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
- return !(!global_variable || !global_variable->hasName() ||
- !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"));
+ return !(
+ !global_variable || !global_variable->hasName() ||
+ !global_variable->getName().starts_with("OBJC_SELECTOR_REFERENCES_"));
}
// This function does not report errors; its callers are responsible.
@@ -801,11 +803,11 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
// is uint8_t*
// Type *sel_type = StructType::get(m_module->getContext());
// Type *sel_ptr_type = PointerType::getUnqual(sel_type);
- Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
+ Type *sel_ptr_type = PointerType::getUnqual(m_module->getContext());
Type *type_array[1];
- type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
+ type_array[0] = llvm::PointerType::getUnqual(m_module->getContext());
ArrayRef<Type *> srN_arg_types(type_array, 1);
@@ -940,7 +942,7 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
llvm::StringRef alloc_name = alloc->getName();
- if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
+ if (alloc_name.starts_with("$") && !alloc_name.starts_with("$__lldb")) {
if (alloc_name.find_first_of("0123456789") == 1) {
LLDB_LOG(log, "Rejecting a numeric persistent variable.");
@@ -1017,7 +1019,7 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
const Type *value_type = nullptr;
- if (name.startswith("$")) {
+ if (name.starts_with("$")) {
// The $__lldb_expr_result name indicates the return value has allocated
// as a static variable. Per the comment at
// ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
@@ -1223,7 +1225,7 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) {
LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
static_cast<void *>(DeclForGlobal(&global_var)));
- if (global_name.startswith("OBJC_IVAR")) {
+ if (global_name.starts_with("OBJC_IVAR")) {
if (!HandleSymbol(&global_var)) {
m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
"indirect ivar symbol {0}\n",
@@ -1641,14 +1643,6 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
}
}
- llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
-
- m_reloc_placeholder = new llvm::GlobalVariable(
- (*m_module), int8_ty, false /* IsConstant */,
- GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
- "reloc_placeholder", nullptr /* InsertBefore */,
- GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
-
////////////////////////////////////////////////////////////
// Replace $__lldb_expr_result with a persistent variable
//
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 eb93952e2b3c..a924187ba04c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -111,43 +111,6 @@ private:
/// True on success; false otherwise.
bool FixFunctionLinkage(llvm::Function &llvm_function);
- /// A module-level pass to replace all function pointers with their
- /// integer equivalents.
-
- /// The top-level pass implementation
- ///
- /// \param[in] llvm_function
- /// The function currently being processed.
- ///
- /// \return
- /// True on success; false otherwise.
- bool HasSideEffects(llvm::Function &llvm_function);
-
- /// A function-level pass to check whether the function has side
- /// effects.
-
- /// Get the address of a function, and a location to put the complete Value
- /// of the function if one is available.
- ///
- /// \param[in] function
- /// The function to find the location of.
- ///
- /// \param[out] ptr
- /// The location of the function in the target.
- ///
- /// \param[out] name
- /// The resolved name of the function (matters for intrinsics).
- ///
- /// \param[out] value_ptr
- /// A variable to put the function's completed Value* in, or NULL
- /// if the Value* shouldn't be stored anywhere.
- ///
- /// \return
- /// The pointer.
- LookupResult GetFunctionAddress(llvm::Function *function, uint64_t &ptr,
- lldb_private::ConstString &name,
- llvm::Constant **&value_ptr);
-
/// A function-level pass to take the generated global value
/// $__lldb_expr_result and make it into a persistent variable. Also see
/// ASTResultSynthesizer.
@@ -170,30 +133,6 @@ public:
private:
clang::NamedDecl *DeclForGlobal(llvm::GlobalValue *global);
- /// Set the constant result variable m_const_result to the provided
- /// constant, assuming it can be evaluated. The result variable will be
- /// reset to NULL later if the expression has side effects.
- ///
- /// \param[in] initializer
- /// The constant initializer for the variable.
- ///
- /// \param[in] name
- /// The name of the result variable.
- ///
- /// \param[in] type
- /// The Clang type of the result variable.
- void MaybeSetConstantResult(llvm::Constant *initializer,
- lldb_private::ConstString name,
- lldb_private::TypeFromParser type);
-
- /// If the IR represents a cast of a variable, set m_const_result to the
- /// result of the cast. The result variable will be reset to
- /// NULL latger if the expression has side effects.
- ///
- /// \param[in] type
- /// The Clang type of the result variable.
- void MaybeSetCastResult(lldb_private::TypeFromParser type);
-
/// The top-level pass implementation
///
/// \param[in] llvm_function
@@ -409,15 +348,9 @@ private:
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 = nullptr;
class FunctionValueCache {
public:
@@ -454,13 +387,6 @@ private:
FunctionValueCache &value_maker,
FunctionValueCache &entry_instruction_finder,
lldb_private::Stream &error_stream);
-
- /// Commit the allocation in m_data_allocator and use its final location to
- /// replace m_reloc_placeholder.
- ///
- /// \return
- /// True on success; false otherwise
- bool CompleteDataAllocation();
};
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
index a67cc8e10c17..da59855a9f16 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
@@ -62,9 +62,9 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
if (extern_c) {
- context = LinkageSpecDecl::Create(
- ast, context, SourceLocation(), SourceLocation(),
- clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
+ context = LinkageSpecDecl::Create(ast, context, SourceLocation(),
+ SourceLocation(),
+ clang::LinkageSpecLanguageIDs::C, false);
// FIXME: The LinkageSpecDecl here should be added to m_decl_context.
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
index 44070b422220..a09c89103b0e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
@@ -9,23 +9,14 @@
#include "InstrumentationRuntimeASan.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Expression/UserExpression.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
+#include "lldb/Target/Process.h"
#include "lldb/Utility/RegularExpression.h"
-#include "lldb/Utility/Stream.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "Plugins/InstrumentationRuntime/Utility/ReportRetriever.h"
using namespace lldb;
using namespace lldb_private;
@@ -69,173 +60,6 @@ bool InstrumentationRuntimeASan::CheckIfRuntimeIsValid(
return symbol != nullptr;
}
-const char *address_sanitizer_retrieve_report_data_prefix = R"(
-extern "C"
-{
-int __asan_report_present();
-void *__asan_get_report_pc();
-void *__asan_get_report_bp();
-void *__asan_get_report_sp();
-void *__asan_get_report_address();
-const char *__asan_get_report_description();
-int __asan_get_report_access_type();
-size_t __asan_get_report_access_size();
-}
-)";
-
-const char *address_sanitizer_retrieve_report_data_command = R"(
-struct {
- int present;
- int access_type;
- void *pc;
- void *bp;
- void *sp;
- void *address;
- size_t access_size;
- const char *description;
-} t;
-
-t.present = __asan_report_present();
-t.access_type = __asan_get_report_access_type();
-t.pc = __asan_get_report_pc();
-t.bp = __asan_get_report_bp();
-t.sp = __asan_get_report_sp();
-t.address = __asan_get_report_address();
-t.access_size = __asan_get_report_access_size();
-t.description = __asan_get_report_description();
-t
-)";
-
-StructuredData::ObjectSP InstrumentationRuntimeASan::RetrieveReportData() {
- ProcessSP process_sp = GetProcessSP();
- if (!process_sp)
- return StructuredData::ObjectSP();
-
- ThreadSP thread_sp =
- process_sp->GetThreadList().GetExpressionExecutionThread();
- StackFrameSP frame_sp =
- thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
-
- if (!frame_sp)
- return StructuredData::ObjectSP();
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(true);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeout(process_sp->GetUtilityExpressionTimeout());
- options.SetPrefix(address_sanitizer_retrieve_report_data_prefix);
- options.SetAutoApplyFixIts(false);
- options.SetLanguage(eLanguageTypeObjC_plus_plus);
-
- ValueObjectSP return_value_sp;
- ExecutionContext exe_ctx;
- Status eval_error;
- frame_sp->CalculateExecutionContext(exe_ctx);
- ExpressionResults result = UserExpression::Evaluate(
- exe_ctx, options, address_sanitizer_retrieve_report_data_command, "",
- return_value_sp, eval_error);
- if (result != eExpressionCompleted) {
- StreamString ss;
- ss << "cannot evaluate AddressSanitizer expression:\n";
- ss << eval_error.AsCString();
- Debugger::ReportWarning(ss.GetString().str(),
- process_sp->GetTarget().GetDebugger().GetID());
- return StructuredData::ObjectSP();
- }
-
- int present = return_value_sp->GetValueForExpressionPath(".present")
- ->GetValueAsUnsigned(0);
- if (present != 1)
- return StructuredData::ObjectSP();
-
- addr_t pc =
- return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0);
- /* commented out because rdar://problem/18533301
- addr_t bp =
- return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0);
- addr_t sp =
- return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0);
- */
- addr_t address = return_value_sp->GetValueForExpressionPath(".address")
- ->GetValueAsUnsigned(0);
- addr_t access_type =
- return_value_sp->GetValueForExpressionPath(".access_type")
- ->GetValueAsUnsigned(0);
- addr_t access_size =
- return_value_sp->GetValueForExpressionPath(".access_size")
- ->GetValueAsUnsigned(0);
- addr_t description_ptr =
- return_value_sp->GetValueForExpressionPath(".description")
- ->GetValueAsUnsigned(0);
- std::string description;
- Status error;
- process_sp->ReadCStringFromMemory(description_ptr, description, error);
-
- StructuredData::Dictionary *dict = new StructuredData::Dictionary();
- dict->AddStringItem("instrumentation_class", "AddressSanitizer");
- dict->AddStringItem("stop_type", "fatal_error");
- dict->AddIntegerItem("pc", pc);
- /* commented out because rdar://problem/18533301
- dict->AddIntegerItem("bp", bp);
- dict->AddIntegerItem("sp", sp);
- */
- dict->AddIntegerItem("address", address);
- dict->AddIntegerItem("access_type", access_type);
- dict->AddIntegerItem("access_size", access_size);
- dict->AddStringItem("description", description);
-
- return StructuredData::ObjectSP(dict);
-}
-
-std::string
-InstrumentationRuntimeASan::FormatDescription(StructuredData::ObjectSP report) {
- std::string description = std::string(report->GetAsDictionary()
- ->GetValueForKey("description")
- ->GetAsString()
- ->GetValue());
- return llvm::StringSwitch<std::string>(description)
- .Case("heap-use-after-free", "Use of deallocated memory")
- .Case("heap-buffer-overflow", "Heap buffer overflow")
- .Case("stack-buffer-underflow", "Stack buffer underflow")
- .Case("initialization-order-fiasco", "Initialization order problem")
- .Case("stack-buffer-overflow", "Stack buffer overflow")
- .Case("stack-use-after-return", "Use of stack memory after return")
- .Case("use-after-poison", "Use of poisoned memory")
- .Case("container-overflow", "Container overflow")
- .Case("stack-use-after-scope", "Use of out-of-scope stack memory")
- .Case("global-buffer-overflow", "Global buffer overflow")
- .Case("unknown-crash", "Invalid memory access")
- .Case("stack-overflow", "Stack space exhausted")
- .Case("null-deref", "Dereference of null pointer")
- .Case("wild-jump", "Jump to non-executable address")
- .Case("wild-addr-write", "Write through wild pointer")
- .Case("wild-addr-read", "Read from wild pointer")
- .Case("wild-addr", "Access through wild pointer")
- .Case("signal", "Deadly signal")
- .Case("double-free", "Deallocation of freed memory")
- .Case("new-delete-type-mismatch",
- "Deallocation size different from allocation size")
- .Case("bad-free", "Deallocation of non-allocated memory")
- .Case("alloc-dealloc-mismatch",
- "Mismatch between allocation and deallocation APIs")
- .Case("bad-malloc_usable_size", "Invalid argument to malloc_usable_size")
- .Case("bad-__sanitizer_get_allocated_size",
- "Invalid argument to __sanitizer_get_allocated_size")
- .Case("param-overlap",
- "Call to function disallowing overlapping memory ranges")
- .Case("negative-size-param", "Negative size used when accessing memory")
- .Case("bad-__sanitizer_annotate_contiguous_container",
- "Invalid argument to __sanitizer_annotate_contiguous_container")
- .Case("odr-violation", "Symbol defined in multiple translation units")
- .Case(
- "invalid-pointer-pair",
- "Comparison or arithmetic on pointers from different memory regions")
- // for unknown report codes just show the code
- .Default("AddressSanitizer detected: " + description);
-}
-
bool InstrumentationRuntimeASan::NotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
@@ -248,32 +72,8 @@ bool InstrumentationRuntimeASan::NotifyBreakpointHit(
ProcessSP process_sp = instance->GetProcessSP();
- if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
- return false;
-
- StructuredData::ObjectSP report = instance->RetrieveReportData();
- std::string description;
- if (report) {
- description = instance->FormatDescription(report);
- }
- // Make sure this is the right process
- if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
- ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
- if (thread_sp)
- thread_sp->SetStopInfo(InstrumentationRuntimeStopInfo::
- CreateStopReasonWithInstrumentationData(
- *thread_sp, description, report));
-
- StreamFileSP stream_sp(
- process_sp->GetTarget().GetDebugger().GetOutputStreamSP());
- if (stream_sp) {
- stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread "
- "info -s' to get extended information about the "
- "report.\n");
- }
- return true; // Return true to stop the target
- } else
- return false; // Let target run
+ return ReportRetriever::NotifyBreakpointHit(process_sp, context, break_id,
+ break_loc_id);
}
void InstrumentationRuntimeASan::Activate() {
@@ -284,29 +84,14 @@ void InstrumentationRuntimeASan::Activate() {
if (!process_sp)
return;
- ConstString symbol_name("_ZN6__asanL7AsanDieEv");
- const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType(
- symbol_name, eSymbolTypeCode);
-
- if (symbol == nullptr)
- return;
+ Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint(
+ GetRuntimeModuleSP(), process_sp, ConstString("_ZN6__asanL7AsanDieEv"));
- if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
+ if (!breakpoint)
return;
- Target &target = process_sp->GetTarget();
- addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
-
- if (symbol_address == LLDB_INVALID_ADDRESS)
- return;
-
- const bool internal = true;
- const bool hardware = false;
const bool sync = false;
- Breakpoint *breakpoint =
- process_sp->GetTarget()
- .CreateBreakpoint(symbol_address, internal, hardware)
- .get();
+
breakpoint->SetCallback(InstrumentationRuntimeASan::NotifyBreakpointHit, this,
sync);
breakpoint->SetBreakpointKind("address-sanitizer-report");
@@ -316,12 +101,13 @@ void InstrumentationRuntimeASan::Activate() {
}
void InstrumentationRuntimeASan::Deactivate() {
- if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
- ProcessSP process_sp = GetProcessSP();
- if (process_sp) {
- process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
- SetBreakpointID(LLDB_INVALID_BREAK_ID);
- }
- }
SetActive(false);
+
+ if (GetBreakpointID() == LLDB_INVALID_BREAK_ID)
+ return;
+
+ if (ProcessSP process_sp = GetProcessSP()) {
+ process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
+ SetBreakpointID(LLDB_INVALID_BREAK_ID);
+ }
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
index 83a88cf7f89f..177959d7126b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
@@ -10,9 +10,6 @@
#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H
#include "lldb/Target/InstrumentationRuntime.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/StructuredData.h"
-#include "lldb/lldb-private.h"
namespace lldb_private {
@@ -51,10 +48,6 @@ private:
StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
-
- StructuredData::ObjectSP RetrieveReportData();
-
- std::string FormatDescription(StructuredData::ObjectSP report);
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp
new file mode 100644
index 000000000000..d84cd36d7ce1
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp
@@ -0,0 +1,120 @@
+//===-- InstrumentationRuntimeASanLibsanitizers.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 "InstrumentationRuntimeASanLibsanitizers.h"
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/RegularExpression.h"
+
+#include "Plugins/InstrumentationRuntime/Utility/ReportRetriever.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASanLibsanitizers)
+
+lldb::InstrumentationRuntimeSP
+InstrumentationRuntimeASanLibsanitizers::CreateInstance(
+ const lldb::ProcessSP &process_sp) {
+ return InstrumentationRuntimeSP(
+ new InstrumentationRuntimeASanLibsanitizers(process_sp));
+}
+
+void InstrumentationRuntimeASanLibsanitizers::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(),
+ "AddressSanitizer instrumentation runtime plugin for Libsanitizers.",
+ CreateInstance, GetTypeStatic);
+}
+
+void InstrumentationRuntimeASanLibsanitizers::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb::InstrumentationRuntimeType
+InstrumentationRuntimeASanLibsanitizers::GetTypeStatic() {
+ return eInstrumentationRuntimeTypeLibsanitizersAsan;
+}
+
+InstrumentationRuntimeASanLibsanitizers::
+ ~InstrumentationRuntimeASanLibsanitizers() {
+ Deactivate();
+}
+
+const RegularExpression &
+InstrumentationRuntimeASanLibsanitizers::GetPatternForRuntimeLibrary() {
+ static RegularExpression regex(
+ llvm::StringRef("libsystem_sanitizers\\.dylib"));
+ return regex;
+}
+
+bool InstrumentationRuntimeASanLibsanitizers::CheckIfRuntimeIsValid(
+ const lldb::ModuleSP module_sp) {
+ const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
+ ConstString("__asan_abi_init"), lldb::eSymbolTypeAny);
+
+ return symbol != nullptr;
+}
+
+bool InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(baton && "null baton");
+ if (!baton)
+ return false;
+
+ InstrumentationRuntimeASanLibsanitizers *const instance =
+ static_cast<InstrumentationRuntimeASanLibsanitizers *>(baton);
+
+ ProcessSP process_sp = instance->GetProcessSP();
+
+ return ReportRetriever::NotifyBreakpointHit(process_sp, context, break_id,
+ break_loc_id);
+}
+
+void InstrumentationRuntimeASanLibsanitizers::Activate() {
+ if (IsActive())
+ return;
+
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return;
+
+ Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint(
+ GetRuntimeModuleSP(), process_sp,
+ ConstString("_Z22raise_sanitizers_error23sanitizer_error_context"));
+
+ if (!breakpoint)
+ return;
+
+ const bool sync = false;
+
+ breakpoint->SetCallback(
+ InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit, this, sync);
+ breakpoint->SetBreakpointKind("address-sanitizer-report");
+ SetBreakpointID(breakpoint->GetID());
+
+ SetActive(true);
+}
+
+void InstrumentationRuntimeASanLibsanitizers::Deactivate() {
+ SetActive(false);
+
+ if (GetBreakpointID() == LLDB_INVALID_BREAK_ID)
+ return;
+
+ if (ProcessSP process_sp = GetProcessSP()) {
+ process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
+ SetBreakpointID(LLDB_INVALID_BREAK_ID);
+ }
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h
new file mode 100644
index 000000000000..abb445a9dd67
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h
@@ -0,0 +1,52 @@
+//===-- InstrumentationRuntimeASanLibsanitizers.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_INSTRUMENTATIONRUNTIME_ASANLIBSANITIZERS_INSTRUMENTATIONRUNTIMEASANLIBSANITIZERS_H
+#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASANLIBSANITIZERS_INSTRUMENTATIONRUNTIMEASANLIBSANITIZERS_H
+
+#include "lldb/Target/InstrumentationRuntime.h"
+
+class InstrumentationRuntimeASanLibsanitizers
+ : public lldb_private::InstrumentationRuntime {
+public:
+ ~InstrumentationRuntimeASanLibsanitizers() override;
+
+ static lldb::InstrumentationRuntimeSP
+ CreateInstance(const lldb::ProcessSP &process_sp);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "Libsanitizers-ASan"; }
+
+ static lldb::InstrumentationRuntimeType GetTypeStatic();
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+ virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); }
+
+private:
+ InstrumentationRuntimeASanLibsanitizers(const lldb::ProcessSP &process_sp)
+ : lldb_private::InstrumentationRuntime(process_sp) {}
+
+ const lldb_private::RegularExpression &GetPatternForRuntimeLibrary() override;
+
+ bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override;
+
+ void Activate() override;
+
+ void Deactivate();
+
+ static bool
+ NotifyBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+};
+
+#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASANLIBSANITIZERS_INSTRUMENTATIONRUNTIMEASANLIBSANITIZERS_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
index 8a5db3335266..2a35256a6fb0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
@@ -14,9 +14,9 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/UserExpression.h"
+#include "lldb/Host/StreamFile.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
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 2e3c053b97bc..1c58922e8d36 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
@@ -14,9 +14,9 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/UserExpression.h"
+#include "lldb/Host/StreamFile.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp
new file mode 100644
index 000000000000..ff58c4cababa
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp
@@ -0,0 +1,252 @@
+//===-- ReportRetriever.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 "ReportRetriever.h"
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *address_sanitizer_retrieve_report_data_prefix = R"(
+extern "C"
+{
+int __asan_report_present();
+void *__asan_get_report_pc();
+void *__asan_get_report_bp();
+void *__asan_get_report_sp();
+void *__asan_get_report_address();
+const char *__asan_get_report_description();
+int __asan_get_report_access_type();
+size_t __asan_get_report_access_size();
+}
+)";
+
+const char *address_sanitizer_retrieve_report_data_command = R"(
+struct {
+ int present;
+ int access_type;
+ void *pc;
+ void *bp;
+ void *sp;
+ void *address;
+ size_t access_size;
+ const char *description;
+} t;
+
+t.present = __asan_report_present();
+t.access_type = __asan_get_report_access_type();
+t.pc = __asan_get_report_pc();
+t.bp = __asan_get_report_bp();
+t.sp = __asan_get_report_sp();
+t.address = __asan_get_report_address();
+t.access_size = __asan_get_report_access_size();
+t.description = __asan_get_report_description();
+t
+)";
+
+StructuredData::ObjectSP
+ReportRetriever::RetrieveReportData(const ProcessSP process_sp) {
+ if (!process_sp)
+ return StructuredData::ObjectSP();
+
+ ThreadSP thread_sp =
+ process_sp->GetThreadList().GetExpressionExecutionThread();
+
+ if (!thread_sp)
+ return StructuredData::ObjectSP();
+
+ StackFrameSP frame_sp =
+ thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
+
+ if (!frame_sp)
+ return StructuredData::ObjectSP();
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(process_sp->GetUtilityExpressionTimeout());
+ options.SetPrefix(address_sanitizer_retrieve_report_data_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeObjC_plus_plus);
+
+ ValueObjectSP return_value_sp;
+ ExecutionContext exe_ctx;
+ Status eval_error;
+ frame_sp->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = UserExpression::Evaluate(
+ exe_ctx, options, address_sanitizer_retrieve_report_data_command, "",
+ return_value_sp, eval_error);
+ if (result != eExpressionCompleted) {
+ StreamString ss;
+ ss << "cannot evaluate AddressSanitizer expression:\n";
+ ss << eval_error.AsCString();
+ Debugger::ReportWarning(ss.GetString().str(),
+ process_sp->GetTarget().GetDebugger().GetID());
+ return StructuredData::ObjectSP();
+ }
+
+ int present = return_value_sp->GetValueForExpressionPath(".present")
+ ->GetValueAsUnsigned(0);
+ if (present != 1)
+ return StructuredData::ObjectSP();
+
+ addr_t pc =
+ return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0);
+ addr_t bp =
+ return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0);
+ addr_t sp =
+ return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0);
+ addr_t address = return_value_sp->GetValueForExpressionPath(".address")
+ ->GetValueAsUnsigned(0);
+ addr_t access_type =
+ return_value_sp->GetValueForExpressionPath(".access_type")
+ ->GetValueAsUnsigned(0);
+ addr_t access_size =
+ return_value_sp->GetValueForExpressionPath(".access_size")
+ ->GetValueAsUnsigned(0);
+ addr_t description_ptr =
+ return_value_sp->GetValueForExpressionPath(".description")
+ ->GetValueAsUnsigned(0);
+ std::string description;
+ Status error;
+ process_sp->ReadCStringFromMemory(description_ptr, description, error);
+
+ auto dict = std::make_shared<StructuredData::Dictionary>();
+ if (!dict)
+ return StructuredData::ObjectSP();
+
+ dict->AddStringItem("instrumentation_class", "AddressSanitizer");
+ dict->AddStringItem("stop_type", "fatal_error");
+ dict->AddIntegerItem("pc", pc);
+ dict->AddIntegerItem("bp", bp);
+ dict->AddIntegerItem("sp", sp);
+ dict->AddIntegerItem("address", address);
+ dict->AddIntegerItem("access_type", access_type);
+ dict->AddIntegerItem("access_size", access_size);
+ dict->AddStringItem("description", description);
+
+ return StructuredData::ObjectSP(dict);
+}
+
+std::string
+ReportRetriever::FormatDescription(StructuredData::ObjectSP report) {
+ std::string description = std::string(report->GetAsDictionary()
+ ->GetValueForKey("description")
+ ->GetAsString()
+ ->GetValue());
+ return llvm::StringSwitch<std::string>(description)
+ .Case("heap-use-after-free", "Use of deallocated memory")
+ .Case("heap-buffer-overflow", "Heap buffer overflow")
+ .Case("stack-buffer-underflow", "Stack buffer underflow")
+ .Case("initialization-order-fiasco", "Initialization order problem")
+ .Case("stack-buffer-overflow", "Stack buffer overflow")
+ .Case("stack-use-after-return", "Use of stack memory after return")
+ .Case("use-after-poison", "Use of poisoned memory")
+ .Case("container-overflow", "Container overflow")
+ .Case("stack-use-after-scope", "Use of out-of-scope stack memory")
+ .Case("global-buffer-overflow", "Global buffer overflow")
+ .Case("unknown-crash", "Invalid memory access")
+ .Case("stack-overflow", "Stack space exhausted")
+ .Case("null-deref", "Dereference of null pointer")
+ .Case("wild-jump", "Jump to non-executable address")
+ .Case("wild-addr-write", "Write through wild pointer")
+ .Case("wild-addr-read", "Read from wild pointer")
+ .Case("wild-addr", "Access through wild pointer")
+ .Case("signal", "Deadly signal")
+ .Case("double-free", "Deallocation of freed memory")
+ .Case("new-delete-type-mismatch",
+ "Deallocation size different from allocation size")
+ .Case("bad-free", "Deallocation of non-allocated memory")
+ .Case("alloc-dealloc-mismatch",
+ "Mismatch between allocation and deallocation APIs")
+ .Case("bad-malloc_usable_size", "Invalid argument to malloc_usable_size")
+ .Case("bad-__sanitizer_get_allocated_size",
+ "Invalid argument to __sanitizer_get_allocated_size")
+ .Case("param-overlap",
+ "Call to function disallowing overlapping memory ranges")
+ .Case("negative-size-param", "Negative size used when accessing memory")
+ .Case("bad-__sanitizer_annotate_contiguous_container",
+ "Invalid argument to __sanitizer_annotate_contiguous_container")
+ .Case("odr-violation", "Symbol defined in multiple translation units")
+ .Case(
+ "invalid-pointer-pair",
+ "Comparison or arithmetic on pointers from different memory regions")
+ // for unknown report codes just show the code
+ .Default("AddressSanitizer detected: " + description);
+}
+
+bool ReportRetriever::NotifyBreakpointHit(ProcessSP process_sp,
+ StoppointCallbackContext *context,
+ user_id_t break_id,
+ user_id_t break_loc_id) {
+ // Make sure this is the right process
+ if (!process_sp || process_sp != context->exe_ctx_ref.GetProcessSP())
+ return false;
+
+ if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+ return false;
+
+ StructuredData::ObjectSP report = RetrieveReportData(process_sp);
+ if (!report || report->GetType() != lldb::eStructuredDataTypeDictionary)
+ return false;
+
+ std::string description = FormatDescription(report);
+
+ if (ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP())
+ thread_sp->SetStopInfo(
+ InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(
+ *thread_sp, description, report));
+
+ if (StreamFileSP stream_sp = StreamFileSP(
+ process_sp->GetTarget().GetDebugger().GetOutputStreamSP()))
+ stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread "
+ "info -s' to get extended information about the "
+ "report.\n");
+
+ return true; // Return true to stop the target
+}
+
+Breakpoint *ReportRetriever::SetupBreakpoint(ModuleSP module_sp,
+ ProcessSP process_sp,
+ ConstString symbol_name) {
+ if (!module_sp || !process_sp)
+ return nullptr;
+
+ const Symbol *symbol =
+ module_sp->FindFirstSymbolWithNameAndType(symbol_name, eSymbolTypeCode);
+
+ if (symbol == nullptr)
+ return nullptr;
+
+ if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
+ return nullptr;
+
+ Target &target = process_sp->GetTarget();
+ addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
+
+ if (symbol_address == LLDB_INVALID_ADDRESS)
+ return nullptr;
+
+ const bool internal = true;
+ const bool hardware = false;
+
+ Breakpoint *breakpoint =
+ process_sp->GetTarget()
+ .CreateBreakpoint(symbol_address, internal, hardware)
+ .get();
+
+ return breakpoint;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h
new file mode 100644
index 000000000000..a45339a5809c
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h
@@ -0,0 +1,34 @@
+//===-- ReportRetriever.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/Process.h"
+
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_REPORTRETRIEVER_H
+#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_REPORTRETRIEVER_H
+
+namespace lldb_private {
+
+class ReportRetriever {
+private:
+ static StructuredData::ObjectSP
+ RetrieveReportData(const lldb::ProcessSP process_sp);
+
+ static std::string FormatDescription(StructuredData::ObjectSP report);
+
+public:
+ static bool NotifyBreakpointHit(lldb::ProcessSP process_sp,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ static Breakpoint *SetupBreakpoint(lldb::ModuleSP, lldb::ProcessSP,
+ ConstString);
+};
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_REPORTRETRIEVER_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index 97d401028d45..73763d9cf3b8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -91,8 +91,8 @@ enum {
class PluginProperties : public Properties {
public:
- static ConstString GetSettingName() {
- return ConstString(JITLoaderGDB::GetPluginNameStatic());
+ static llvm::StringRef GetSettingName() {
+ return JITLoaderGDB::GetPluginNameStatic();
}
PluginProperties() {
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 e780cd8285c4..314a4aca8d26 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -54,18 +54,6 @@ public:
if (!clang_ast_context)
return;
- std::shared_ptr<ClangASTImporter> clang_ast_importer;
- auto *state = target_sp->GetPersistentExpressionStateForLanguage(
- lldb::eLanguageTypeC_plus_plus);
- if (state) {
- auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
- clang_ast_importer = persistent_vars->GetClangASTImporter();
- }
-
- if (!clang_ast_importer) {
- return;
- }
-
const char *const isa_name("__isa");
const CompilerType isa_type =
clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
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 3d709e3d6759..586cc08a6f12 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -45,6 +45,7 @@
#include "LibCxxVariant.h"
#include "LibStdcpp.h"
#include "MSVCUndecoratedNameParser.h"
+#include "lldb/lldb-enumerations.h"
using namespace lldb;
using namespace lldb_private;
@@ -332,14 +333,12 @@ bool CPlusPlusLanguage::MethodName::ContainsPath(llvm::StringRef path) {
// If we can't parse the incoming name, then just check that it contains path.
if (m_parse_error)
return m_full.GetStringRef().contains(path);
-
+
llvm::StringRef identifier;
llvm::StringRef context;
std::string path_str = path.str();
- bool success
- = CPlusPlusLanguage::ExtractContextAndIdentifier(path_str.c_str(),
- context,
- identifier);
+ bool success = CPlusPlusLanguage::ExtractContextAndIdentifier(
+ path_str.c_str(), context, identifier);
if (!success)
return m_full.GetStringRef().contains(path);
@@ -372,7 +371,7 @@ bool CPlusPlusLanguage::MethodName::ContainsPath(llvm::StringRef path) {
return false;
if (haystack.empty() || !isalnum(haystack.back()))
return true;
-
+
return false;
}
@@ -388,7 +387,7 @@ bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) {
return true;
}
-bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path,
+bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path,
ConstString demangled) const {
MethodName demangled_name(demangled);
return demangled_name.ContainsPath(path);
@@ -467,7 +466,7 @@ protected:
}
void trySubstitute(llvm::StringRef From, llvm::StringRef To) {
- if (!llvm::StringRef(currentParserPos(), this->numLeft()).startswith(From))
+ if (!llvm::StringRef(currentParserPos(), this->numLeft()).starts_with(From))
return;
// We found a match. Append unmodified input up to this point.
@@ -981,6 +980,57 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"std::unordered_map iterator synthetic children",
"^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$",
stl_synth_flags, true);
+ // Chrono duration typedefs
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::nanoseconds", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(
+ eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ns")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::microseconds", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(
+ eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} µs")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::milliseconds", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(
+ eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ms")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(
+ eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::minutes", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+ eTypeOptionHideValue,
+ "${var.__rep_} min")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::hours", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(
+ eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} h")));
+
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::days", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+ eTypeOptionHideValue,
+ "${var.__rep_} days")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::weeks", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+ eTypeOptionHideValue,
+ "${var.__rep_} weeks")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::months", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+ eTypeOptionHideValue,
+ "${var.__rep_} months")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::years", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+ eTypeOptionHideValue,
+ "${var.__rep_} years")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,
+ TypeSummaryImplSP(new StringSummaryFormat(
+ eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
}
static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
@@ -1009,7 +1059,7 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp->AddTypeSummary("std::string", eFormatterMatchExact,
std_string_summary_sp);
cpp_category_sp->AddTypeSummary("std::basic_string<char>",
- eFormatterMatchRegex, std_string_summary_sp);
+ eFormatterMatchExact, std_string_summary_sp);
cpp_category_sp->AddTypeSummary(
"std::basic_string<char,std::char_traits<char>,std::allocator<char> >",
eFormatterMatchExact, std_string_summary_sp);
@@ -1104,6 +1154,11 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));
+ cpp_category_sp->AddTypeSynthetic(
+ "^std::variant<.+>$", eFormatterMatchRegex,
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
@@ -1148,6 +1203,11 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(new ScriptSummaryFormat(
stl_summary_flags,
"lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
+ cpp_category_sp->AddTypeSummary(
+ "^std::variant<.+>$", eFormatterMatchRegex,
+ TypeSummaryImplSP(new ScriptSummaryFormat(
+ stl_summary_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider")));
AddCXXSynthetic(
cpp_category_sp,
@@ -1356,7 +1416,8 @@ CPlusPlusLanguage::GetHardcodedSummaries() {
lldb_private::formatters::CXXFunctionPointerSummaryProvider,
"Function pointer summary provider"));
if (CompilerType CT = valobj.GetCompilerType();
- CT.IsFunctionPointerType() || CT.IsMemberFunctionPointerType()) {
+ CT.IsFunctionPointerType() || CT.IsMemberFunctionPointerType() ||
+ valobj.GetValueType() == lldb::eValueTypeVTableEntry) {
return formatter_sp;
}
return nullptr;
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 7712a60b7795..623d481bf117 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -103,6 +103,8 @@ public:
return lldb::eLanguageTypeC_plus_plus;
}
+ llvm::StringRef GetUserEntryPointName() const override { return "main"; }
+
std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
lldb::TypeCategoryImplSP GetFormatters() override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index cd3ac92ae4a8..2876efc5c41a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -38,7 +38,7 @@ public:
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
- ConstString GetDataContainerMemberName();
+ llvm::StringRef GetDataContainerMemberName();
// The lifetime of a ValueObject and all its derivative ValueObjects
// (children, clones, etc.) is managed by a ClusterManager. These
@@ -66,12 +66,14 @@ GenericBitsetFrontEnd::GenericBitsetFrontEnd(ValueObject &valobj, StdLib stdlib)
}
}
-ConstString GenericBitsetFrontEnd::GetDataContainerMemberName() {
+llvm::StringRef GenericBitsetFrontEnd::GetDataContainerMemberName() {
+ static constexpr llvm::StringLiteral s_libcxx_case("__first_");
+ static constexpr llvm::StringLiteral s_libstdcpp_case("_M_w");
switch (m_stdlib) {
case StdLib::LibCxx:
- return ConstString("__first_");
+ return s_libcxx_case;
case StdLib::LibStdcpp:
- return ConstString("_M_w");
+ return s_libstdcpp_case;
}
llvm_unreachable("Unknown StdLib enum");
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 14776cdf8081..ff7043bdf97f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -84,7 +84,7 @@ static bool isStdTemplate(ConstString type_name, llvm::StringRef type) {
// The type name may be prefixed with `std::__<inline-namespace>::`.
if (name.consume_front("std::"))
consumeInlineNamespace(name);
- return name.consume_front(type) && name.startswith("<");
+ return name.consume_front(type) && name.starts_with("<");
}
static bool isUnorderedMap(ConstString type_name) {
@@ -162,10 +162,27 @@ lldb::ValueObjectSP lldb_private::formatters::
if (!node_sp || error.Fail())
return nullptr;
- value_sp = node_sp->GetChildMemberWithName("__value_");
hash_sp = node_sp->GetChildMemberWithName("__hash_");
- if (!value_sp || !hash_sp)
+ if (!hash_sp)
return nullptr;
+
+ value_sp = node_sp->GetChildMemberWithName("__value_");
+ if (!value_sp) {
+ // clang-format off
+ // Since D101206 (ba79fb2e1f), libc++ wraps the `__value_` in an
+ // anonymous union.
+ // Child 0: __hash_node_base base class
+ // Child 1: __hash_
+ // Child 2: anonymous union
+ // clang-format on
+ auto anon_union_sp = node_sp->GetChildAtIndex(2);
+ if (!anon_union_sp)
+ return nullptr;
+
+ value_sp = anon_union_sp->GetChildMemberWithName("__value_");
+ if (!value_sp)
+ return nullptr;
+ }
}
m_elements_cache.push_back(
{value_sp.get(), hash_sp->GetValueAsUnsigned(0)});
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index c65bb9b6bc9b..23af50fdb712 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -377,9 +377,16 @@ lldb::ValueObjectSP
LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
if (idx == 0)
return m_ptr_obj->GetSP();
- if (idx == 1)
- return m_obj_obj->GetSP();
-
+ if (idx == 1) {
+ if (m_ptr_obj && !m_obj_obj) {
+ Status error;
+ ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
+ if (error.Success())
+ m_obj_obj = obj_obj->Clone(ConstString("object")).get();
+ }
+ if (m_obj_obj)
+ return m_obj_obj->GetSP();
+ }
return lldb::ValueObjectSP();
}
@@ -397,14 +404,7 @@ bool LibStdcppSharedPtrSyntheticFrontEnd::Update() {
return false;
m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();
-
- if (m_ptr_obj) {
- Status error;
- ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
- if (error.Success()) {
- m_obj_obj = obj_obj->Clone(ConstString("object")).get();
- }
- }
+ m_obj_obj = nullptr;
return false;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
index aef7cbac603f..f1bfeae5099b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
@@ -69,9 +69,9 @@ bool LibStdcppTupleSyntheticFrontEnd::Update() {
for (size_t i = 0; i < child_count; ++i) {
ValueObjectSP child_sp = current_child->GetChildAtIndex(i);
llvm::StringRef name_str = child_sp->GetName().GetStringRef();
- if (name_str.startswith("std::_Tuple_impl<")) {
+ if (name_str.starts_with("std::_Tuple_impl<")) {
next_child_sp = child_sp;
- } else if (name_str.startswith("std::_Head_base<")) {
+ } else if (name_str.starts_with("std::_Head_base<")) {
ValueObjectSP value_sp =
child_sp->GetChildMemberWithName("_M_head_impl");
if (value_sp) {
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 7174e9102e1b..a84d641b57bc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -108,14 +108,7 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
if (del_obj)
m_del_obj = del_obj->Clone(ConstString("deleter")).get();
}
-
- if (m_ptr_obj) {
- Status error;
- ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
- if (error.Success()) {
- m_obj_obj = obj_obj->Clone(ConstString("object")).get();
- }
- }
+ m_obj_obj = nullptr;
return false;
}
@@ -128,8 +121,17 @@ LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
return m_ptr_obj->GetSP();
if (idx == 1 && m_del_obj)
return m_del_obj->GetSP();
- if (idx == 2 && m_obj_obj)
- return m_obj_obj->GetSP();
+ if (idx == 2) {
+ if (m_ptr_obj && !m_obj_obj) {
+ Status error;
+ ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
+ if (error.Success()) {
+ m_obj_obj = obj_obj->Clone(ConstString("object")).get();
+ }
+ }
+ if (m_obj_obj)
+ return m_obj_obj->GetSP();
+ }
return lldb::ValueObjectSP();
}
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 374ac763ab18..f1a7e04bc9d1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -237,7 +237,8 @@ bool lldb_private::formatters::NSIndexSetSummaryProvider(
if (!process_sp)
return false;
- ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
+ AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
+ ObjCLanguageRuntime::Get(*process_sp));
if (!runtime)
return false;
@@ -264,20 +265,56 @@ bool lldb_private::formatters::NSIndexSetSummaryProvider(
do {
if (class_name == "NSIndexSet" || class_name == "NSMutableIndexSet") {
+ // Foundation version 2000 added a bitmask if the index set fit in 64 bits
+ // and a Tagged Pointer version if the bitmask is small enough to fit in
+ // the tagged pointer payload.
+ // It also changed the layout (but not the size) of the set descriptor.
+
+ // First check whether this is a tagged pointer. The bitmask will be in
+ // the payload of the tagged pointer.
+ uint64_t payload;
+ if (runtime->GetFoundationVersion() >= 2000
+ && descriptor->GetTaggedPointerInfo(nullptr, nullptr, &payload)) {
+ count = llvm::popcount(payload);
+ break;
+ }
+ // The first 32 bits describe the index set in all cases:
Status error;
uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(
- valobj_addr + ptr_size, 4, 0, error);
+ valobj_addr + ptr_size, 4, 0, error);
if (error.Fail())
return false;
- // this means the set is empty - count = 0
- if ((mode & 1) == 1) {
- count = 0;
- break;
+ // Now check if the index is held in a bitmask in the object:
+ if (runtime->GetFoundationVersion() >= 2000) {
+ // The first two bits are "isSingleRange" and "isBitfield". If this is
+ // a bitfield we handle it here, otherwise set mode appropriately and
+ // the rest of the treatment is in common.
+ if ((mode & 2) == 2) {
+ // The bitfield is a 64 bit uint at the beginning of the data var.
+ uint64_t bitfield = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + 2 * ptr_size, 8, 0, error);
+ if (error.Fail())
+ return false;
+ count = llvm::popcount(bitfield);
+ break;
+ }
+ // It wasn't a bitfield, so read the isSingleRange from its new loc:
+ if ((mode & 1) == 1)
+ mode = 1; // this means the set only has one range
+ else
+ mode = 2; // this means the set has multiple ranges
+ } else {
+ // this means the set is empty - count = 0
+ if ((mode & 1) == 1) {
+ count = 0;
+ break;
+ }
+
+ if ((mode & 2) == 2)
+ mode = 1; // this means the set only has one range
+ else
+ mode = 2; // this means the set has multiple ranges
}
- if ((mode & 2) == 2)
- mode = 1; // this means the set only has one range
- else
- mode = 2; // this means the set has multiple ranges
if (mode == 1) {
count = process_sp->ReadUnsignedIntegerFromMemory(
valobj_addr + 3 * ptr_size, ptr_size, 0, error);
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 2e927eb8d856..5ae0751cb065 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -37,7 +37,7 @@ NSDictionary_Additionals::AdditionalFormatterMatching::Prefix::Prefix(
bool NSDictionary_Additionals::AdditionalFormatterMatching::Prefix::Match(
ConstString class_name) {
- return class_name.GetStringRef().startswith(m_prefix.GetStringRef());
+ return class_name.GetStringRef().starts_with(m_prefix.GetStringRef());
}
NSDictionary_Additionals::AdditionalFormatterMatching::Full::Full(ConstString n)
@@ -78,7 +78,8 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
if (!compiler_type) {
compiler_type = scratch_ts_sp->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
- g_lldb_autogen_nspair, clang::TTK_Struct, lldb::eLanguageTypeC);
+ g_lldb_autogen_nspair, llvm::to_underlying(clang::TagTypeKind::Struct),
+ lldb::eLanguageTypeC);
if (compiler_type) {
TypeSystemClang::StartTagDeclarationDefinition(compiler_type);
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 82b037129c24..742ae7b14945 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -81,9 +81,9 @@ ObjCLanguage::MethodName::Create(llvm::StringRef name, bool strict) {
// Figure out type
Type type = eTypeUnspecified;
- if (name.startswith("+["))
+ if (name.starts_with("+["))
type = eTypeClassMethod;
- else if (name.startswith("-["))
+ else if (name.starts_with("-["))
type = eTypeInstanceMethod;
// If there's no type and it's strict, this is invalid
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 bb8057846bb7..a50f4b036108 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -127,6 +127,8 @@ public:
return lldb::eLanguageTypeObjC;
}
+ llvm::StringRef GetUserEntryPointName() const override { return "main"; }
+
// Get all possible names for a method. Examples:
// If method_name is "+[NSString(my_additions) myStringWithCString:]"
// variant_names[0] => "+[NSString myStringWithCString:]"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index b7c71b5dbb1c..1beab9348eb7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -27,6 +27,8 @@ public:
return lldb::eLanguageTypeObjC_plus_plus;
}
+ llvm::StringRef GetUserEntryPointName() const override { return "main"; }
+
llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
bool IsSourceFile(llvm::StringRef file_path) const override;
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 c2488eaa9f5b..300ecc8e8ed5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -34,6 +34,9 @@ using namespace lldb;
using namespace lldb_private;
static ConstString g_this = ConstString("this");
+// Artificial coroutine-related variables emitted by clang.
+static ConstString g_promise = ConstString("__promise");
+static ConstString g_coro_frame = ConstString("__coro_frame");
char CPPLanguageRuntime::ID = 0;
@@ -41,7 +44,7 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
: LanguageRuntime(process) {}
bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
- return name == g_this;
+ return name == g_this || name == g_promise || name == g_coro_frame;
}
bool CPPLanguageRuntime::GetObjectDescription(Stream &str,
@@ -217,7 +220,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
llvm::StringRef vtable_name(symbol->GetName().GetStringRef());
bool found_expected_start_string =
- vtable_name.startswith("vtable for std::__1::__function::__func<");
+ vtable_name.starts_with("vtable for std::__1::__function::__func<");
if (!found_expected_start_string)
return optional_info;
@@ -274,7 +277,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
}
// Case 4 or 5
- if (symbol && !symbol->GetName().GetStringRef().startswith("vtable for") &&
+ if (symbol && !symbol->GetName().GetStringRef().starts_with("vtable for") &&
!contains_lambda_identifier(first_template_parameter) && !has_invoke) {
optional_info.callable_case =
LibCppStdFunctionCallableCase::FreeOrMemberFunction;
@@ -309,7 +312,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
lldb::FunctionSP func_sp =
vtable_cu->FindFunction([name_to_use](const FunctionSP &f) {
auto name = f->GetName().GetStringRef();
- if (name.startswith(name_to_use) && name.contains("operator"))
+ if (name.starts_with(name_to_use) && name.contains("operator"))
return true;
return false;
@@ -370,7 +373,7 @@ CPPLanguageRuntime::GetStepThroughTrampolinePlan(Thread &thread,
// step into the wrapped callable.
//
bool found_expected_start_string =
- function_name.startswith("std::__1::function<");
+ function_name.starts_with("std::__1::function<");
if (!found_expected_start_string)
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 711a696ff9b4..47b1db16f1e9 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
@@ -54,134 +54,237 @@ bool ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
check_objc);
}
-TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
- ValueObject &in_value, lldb::addr_t original_ptr,
- lldb::addr_t vtable_load_addr) {
- if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) {
- // Find the symbol that contains the "vtable_load_addr" address
- Address vtable_addr;
- Target &target = m_process->GetTarget();
- if (!target.GetSectionLoadList().IsEmpty()) {
- if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr,
- vtable_addr)) {
- // See if we have cached info for this type already
- TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
- if (type_info)
- return type_info;
-
- SymbolContext sc;
- target.GetImages().ResolveSymbolContextForAddress(
- vtable_addr, eSymbolContextSymbol, sc);
- Symbol *symbol = sc.symbol;
- if (symbol != nullptr) {
- const char *name =
- symbol->GetMangled().GetDemangledName().AsCString();
- if (name && strstr(name, vtable_demangled_prefix) == name) {
- Log *log = GetLog(LLDBLog::Object);
- LLDB_LOGF(log,
- "0x%16.16" PRIx64
- ": static-type = '%s' has vtable symbol '%s'\n",
- original_ptr, in_value.GetTypeName().GetCString(), name);
- // We are a C++ class, that's good. Get the class name and look it
- // up:
- const char *class_name = name + strlen(vtable_demangled_prefix);
- // We know the class name is absolute, so tell FindTypes that by
- // prefixing it with the root namespace:
- std::string lookup_name("::");
- lookup_name.append(class_name);
-
- type_info.SetName(class_name);
- const bool exact_match = true;
- TypeList class_types;
-
- // First look in the module that the vtable symbol came from and
- // look for a single exact match.
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- if (sc.module_sp)
- sc.module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
- searched_symbol_files, class_types);
-
- // If we didn't find a symbol, then move on to the entire module
- // list in the target and get as many unique matches as possible
- if (class_types.Empty())
- target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
- exact_match, UINT32_MAX,
- searched_symbol_files, class_types);
-
- lldb::TypeSP type_sp;
- if (class_types.Empty()) {
- LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
- original_ptr);
- return TypeAndOrName();
+TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
+ ValueObject &in_value, const VTableInfo &vtable_info) {
+ if (vtable_info.addr.IsSectionOffset()) {
+ // See if we have cached info for this type already
+ TypeAndOrName type_info = GetDynamicTypeInfo(vtable_info.addr);
+ if (type_info)
+ return type_info;
+
+ if (vtable_info.symbol) {
+ Log *log = GetLog(LLDBLog::Object);
+ llvm::StringRef symbol_name =
+ vtable_info.symbol->GetMangled().GetDemangledName().GetStringRef();
+ LLDB_LOGF(log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has vtable symbol '%s'\n",
+ in_value.GetPointerValue(),
+ in_value.GetTypeName().GetCString(),
+ symbol_name.str().c_str());
+ // We are a C++ class, that's good. Get the class name and look it
+ // up:
+ llvm::StringRef class_name = symbol_name;
+ class_name.consume_front(vtable_demangled_prefix);
+ // We know the class name is absolute, so tell FindTypes that by
+ // prefixing it with the root namespace:
+ std::string lookup_name("::");
+ lookup_name.append(class_name.data(), class_name.size());
+
+ type_info.SetName(class_name);
+ ConstString const_lookup_name(lookup_name);
+ TypeList class_types;
+ ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
+ // First look in the module that the vtable symbol came from and
+ // look for a single exact match.
+ TypeResults results;
+ TypeQuery query(const_lookup_name.GetStringRef(),
+ TypeQueryOptions::e_exact_match |
+ TypeQueryOptions::e_find_one);
+ if (module_sp) {
+ module_sp->FindTypes(query, results);
+ TypeSP type_sp = results.GetFirstType();
+ if (type_sp)
+ class_types.Insert(type_sp);
+ }
+
+ // If we didn't find a symbol, then move on to the entire module
+ // list in the target and get as many unique matches as possible
+ if (class_types.Empty()) {
+ query.SetFindOne(false);
+ m_process->GetTarget().GetImages().FindTypes(nullptr, query, results);
+ for (const auto &type_sp : results.GetTypeMap().Types())
+ class_types.Insert(type_sp);
+ }
+
+ lldb::TypeSP type_sp;
+ if (class_types.Empty()) {
+ LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
+ in_value.GetPointerValue());
+ return TypeAndOrName();
+ }
+ if (class_types.GetSize() == 1) {
+ type_sp = class_types.GetTypeAtIndex(0);
+ if (type_sp) {
+ if (TypeSystemClang::IsCXXClassType(
+ type_sp->GetForwardCompilerType())) {
+ LLDB_LOGF(
+ log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
+ "}, type-name='%s'\n",
+ in_value.GetPointerValue(), in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ type_info.SetTypeSP(type_sp);
+ }
+ }
+ } else {
+ size_t i;
+ if (log) {
+ for (i = 0; i < class_types.GetSize(); i++) {
+ type_sp = class_types.GetTypeAtIndex(i);
+ if (type_sp) {
+ LLDB_LOGF(
+ log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
+ in_value.GetPointerValue(),
+ in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
}
- if (class_types.GetSize() == 1) {
- type_sp = class_types.GetTypeAtIndex(0);
- if (type_sp) {
- if (TypeSystemClang::IsCXXClassType(
- type_sp->GetForwardCompilerType())) {
- LLDB_LOGF(
- log,
- "0x%16.16" PRIx64
- ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
- "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(),
- type_sp->GetID(), type_sp->GetName().GetCString());
- type_info.SetTypeSP(type_sp);
- }
- }
- } else {
- size_t i;
- if (log) {
- for (i = 0; i < class_types.GetSize(); i++) {
- type_sp = class_types.GetTypeAtIndex(i);
- if (type_sp) {
- LLDB_LOGF(
- log,
- "0x%16.16" PRIx64
- ": static-type = '%s' has multiple matching dynamic "
- "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(),
- type_sp->GetID(), type_sp->GetName().GetCString());
- }
- }
- }
-
- for (i = 0; i < class_types.GetSize(); i++) {
- type_sp = class_types.GetTypeAtIndex(i);
- if (type_sp) {
- if (TypeSystemClang::IsCXXClassType(
- type_sp->GetForwardCompilerType())) {
- LLDB_LOGF(
- log,
- "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
- "matching dynamic types, picking "
- "this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(),
- type_sp->GetID(), type_sp->GetName().GetCString());
- type_info.SetTypeSP(type_sp);
- }
- }
- }
-
- if (log) {
- LLDB_LOGF(log,
- "0x%16.16" PRIx64
- ": static-type = '%s' has multiple matching dynamic "
- "types, didn't find a C++ match\n",
- original_ptr, in_value.GetTypeName().AsCString());
- }
+ }
+ }
+
+ for (i = 0; i < class_types.GetSize(); i++) {
+ type_sp = class_types.GetTypeAtIndex(i);
+ if (type_sp) {
+ if (TypeSystemClang::IsCXXClassType(
+ type_sp->GetForwardCompilerType())) {
+ LLDB_LOGF(
+ log,
+ "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
+ "matching dynamic types, picking "
+ "this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
+ in_value.GetPointerValue(),
+ in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ type_info.SetTypeSP(type_sp);
}
- if (type_info)
- SetDynamicTypeInfo(vtable_addr, type_info);
- return type_info;
}
}
+
+ if (log) {
+ LLDB_LOGF(log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types, didn't find a C++ match\n",
+ in_value.GetPointerValue(),
+ in_value.GetTypeName().AsCString());
+ }
}
+ if (type_info)
+ SetDynamicTypeInfo(vtable_info.addr, type_info);
+ return type_info;
}
}
return TypeAndOrName();
}
+llvm::Error ItaniumABILanguageRuntime::TypeHasVTable(CompilerType type) {
+ // Check to make sure the class has a vtable.
+ CompilerType original_type = type;
+ if (type.IsPointerOrReferenceType()) {
+ CompilerType pointee_type = type.GetPointeeType();
+ if (pointee_type)
+ type = pointee_type;
+ }
+
+ // Make sure this is a class or a struct first by checking the type class
+ // bitfield that gets returned.
+ if ((type.GetTypeClass() & (eTypeClassStruct | eTypeClassClass)) == 0) {
+ return llvm::createStringError(std::errc::invalid_argument,
+ "type \"%s\" is not a class or struct or a pointer to one",
+ original_type.GetTypeName().AsCString("<invalid>"));
+ }
+
+ // Check if the type has virtual functions by asking it if it is polymorphic.
+ if (!type.IsPolymorphicClass()) {
+ return llvm::createStringError(std::errc::invalid_argument,
+ "type \"%s\" doesn't have a vtable",
+ type.GetTypeName().AsCString("<invalid>"));
+ }
+ return llvm::Error::success();
+}
+
+// This function can accept both pointers or references to classes as well as
+// instances of classes. If you are using this function during dynamic type
+// detection, only valid ValueObjects that return true to
+// CouldHaveDynamicValue(...) should call this function and \a check_type
+// should be set to false. This function is also used by ValueObjectVTable
+// and is can pass in instances of classes which is not suitable for dynamic
+// type detection, these cases should pass true for \a check_type.
+llvm::Expected<LanguageRuntime::VTableInfo>
+ ItaniumABILanguageRuntime::GetVTableInfo(ValueObject &in_value,
+ bool check_type) {
+
+ CompilerType type = in_value.GetCompilerType();
+ if (check_type) {
+ if (llvm::Error err = TypeHasVTable(type))
+ return std::move(err);
+ }
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process == nullptr)
+ return llvm::createStringError(std::errc::invalid_argument,
+ "invalid process");
+
+ AddressType address_type;
+ lldb::addr_t original_ptr = LLDB_INVALID_ADDRESS;
+ if (type.IsPointerOrReferenceType())
+ original_ptr = in_value.GetPointerValue(&address_type);
+ else
+ original_ptr = in_value.GetAddressOf(/*scalar_is_load_address=*/true,
+ &address_type);
+ if (original_ptr == LLDB_INVALID_ADDRESS || address_type != eAddressTypeLoad)
+ return llvm::createStringError(std::errc::invalid_argument,
+ "failed to get the address of the value");
+
+ Status error;
+ lldb::addr_t vtable_load_addr =
+ process->ReadPointerFromMemory(original_ptr, error);
+
+ if (!error.Success() || vtable_load_addr == LLDB_INVALID_ADDRESS)
+ return llvm::createStringError(std::errc::invalid_argument,
+ "failed to read vtable pointer from memory at 0x%" PRIx64,
+ original_ptr);
+
+ // The vtable load address can have authentication bits with
+ // AArch64 targets on Darwin.
+ vtable_load_addr = process->FixDataAddress(vtable_load_addr);
+
+ // Find the symbol that contains the "vtable_load_addr" address
+ Address vtable_addr;
+ if (!process->GetTarget().ResolveLoadAddress(vtable_load_addr, vtable_addr))
+ return llvm::createStringError(std::errc::invalid_argument,
+ "failed to resolve vtable pointer 0x%"
+ PRIx64 "to a section", vtable_load_addr);
+
+ // Check our cache first to see if we already have this info
+ {
+ std::lock_guard<std::mutex> locker(m_mutex);
+ auto pos = m_vtable_info_map.find(vtable_addr);
+ if (pos != m_vtable_info_map.end())
+ return pos->second;
+ }
+
+ Symbol *symbol = vtable_addr.CalculateSymbolContextSymbol();
+ if (symbol == nullptr)
+ return llvm::createStringError(std::errc::invalid_argument,
+ "no symbol found for 0x%" PRIx64,
+ vtable_load_addr);
+ llvm::StringRef name = symbol->GetMangled().GetDemangledName().GetStringRef();
+ if (name.starts_with(vtable_demangled_prefix)) {
+ VTableInfo info = {vtable_addr, symbol};
+ std::lock_guard<std::mutex> locker(m_mutex);
+ auto pos = m_vtable_info_map[vtable_addr] = info;
+ return info;
+ }
+ return llvm::createStringError(std::errc::invalid_argument,
+ "symbol found that contains 0x%" PRIx64 " is not a vtable symbol",
+ vtable_load_addr);
+}
+
bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &dynamic_address,
@@ -198,33 +301,23 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
class_type_or_name.Clear();
value_type = Value::ValueType::Scalar;
- // Only a pointer or reference type can have a different dynamic and static
- // type:
if (!CouldHaveDynamicValue(in_value))
return false;
- // First job, pull out the address at 0 offset from the object.
- AddressType address_type;
- lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
- if (original_ptr == LLDB_INVALID_ADDRESS)
- return false;
-
- ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
-
- Process *process = exe_ctx.GetProcessPtr();
-
- if (process == nullptr)
- return false;
-
- Status error;
- const lldb::addr_t vtable_address_point =
- process->ReadPointerFromMemory(original_ptr, error);
-
- if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS)
+ // Check if we have a vtable pointer in this value. If we don't it will
+ // return an error, else it will return a valid resolved address. We don't
+ // want GetVTableInfo to check the type since we accept void * as a possible
+ // dynamic type and that won't pass the type check. We already checked the
+ // type above in CouldHaveDynamicValue(...).
+ llvm::Expected<VTableInfo> vtable_info_or_err =
+ GetVTableInfo(in_value, /*check_type=*/false);
+ if (!vtable_info_or_err) {
+ llvm::consumeError(vtable_info_or_err.takeError());
return false;
+ }
- class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr,
- vtable_address_point);
+ const VTableInfo &vtable_info = vtable_info_or_err.get();
+ class_type_or_name = GetTypeInfo(in_value, vtable_info);
if (!class_type_or_name)
return false;
@@ -244,22 +337,27 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
}
// The offset_to_top is two pointers above the vtable pointer.
- const uint32_t addr_byte_size = process->GetAddressByteSize();
+ Target &target = m_process->GetTarget();
+ const addr_t vtable_load_addr = vtable_info.addr.GetLoadAddress(&target);
+ if (vtable_load_addr == LLDB_INVALID_ADDRESS)
+ return false;
+ const uint32_t addr_byte_size = m_process->GetAddressByteSize();
const lldb::addr_t offset_to_top_location =
- vtable_address_point - 2 * addr_byte_size;
+ vtable_load_addr - 2 * addr_byte_size;
// Watch for underflow, offset_to_top_location should be less than
- // vtable_address_point
- if (offset_to_top_location >= vtable_address_point)
+ // vtable_load_addr
+ if (offset_to_top_location >= vtable_load_addr)
return false;
- const int64_t offset_to_top = process->ReadSignedIntegerFromMemory(
+ Status error;
+ const int64_t offset_to_top = m_process->ReadSignedIntegerFromMemory(
offset_to_top_location, addr_byte_size, INT64_MIN, error);
if (offset_to_top == INT64_MIN)
return false;
// So the dynamic type is a value that starts at offset_to_top above
// the original address.
- lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
- if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress(
+ lldb::addr_t dynamic_addr = in_value.GetPointerValue() + offset_to_top;
+ if (!m_process->GetTarget().ResolveLoadAddress(
dynamic_addr, dynamic_address)) {
dynamic_address.SetRawAddress(dynamic_addr);
}
@@ -339,7 +437,7 @@ public:
~CommandObjectMultiwordItaniumABI_Demangle() override = default;
protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
bool demangled_any = false;
bool error_any = false;
for (auto &entry : command.entries()) {
@@ -352,7 +450,7 @@ protected:
// on behalf of the user. This is the moral equivalent of the -_/-n
// options to c++filt
auto name = entry.ref();
- if (name.startswith("__Z"))
+ if (name.starts_with("__Z"))
name = name.drop_front();
Mangled mangled(name);
@@ -372,7 +470,6 @@ protected:
error_any ? lldb::eReturnStatusFailed
: (demangled_any ? lldb::eReturnStatusSuccessFinishResult
: lldb::eReturnStatusSuccessFinishNoResult));
- return result.Succeeded();
}
};
@@ -516,7 +613,7 @@ bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop(
return false;
uint64_t break_site_id = stop_reason->GetValue();
- return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(
+ return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
break_site_id, m_cxx_exception_bp_sp->GetID());
}
@@ -583,10 +680,10 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread(
ValueObjectSP exception = ValueObject::CreateValueObjectFromData(
"exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx,
voidstar);
- ValueObjectSP dyn_exception
+ ValueObjectSP dyn_exception
= exception->GetDynamicValue(eDynamicDontRunTarget);
// If we succeed in making a dynamic value, return that:
- if (dyn_exception)
+ if (dyn_exception)
return dyn_exception;
return exception;
@@ -594,7 +691,7 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread(
TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo(
const lldb_private::Address &vtable_addr) {
- std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ std::lock_guard<std::mutex> locker(m_mutex);
DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
if (pos == m_dynamic_type_map.end())
return TypeAndOrName();
@@ -604,6 +701,6 @@ TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo(
void ItaniumABILanguageRuntime::SetDynamicTypeInfo(
const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info) {
- std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ std::lock_guard<std::mutex> locker(m_mutex);
m_dynamic_type_map[vtable_addr] = type_info;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index ca8d5ab1a93a..0f7e73cfee07 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -47,6 +47,10 @@ public:
return runtime->isA(&ID);
}
+
+ llvm::Expected<LanguageRuntime::VTableInfo>
+ GetVTableInfo(ValueObject &in_value, bool check_type) override;
+
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
@@ -71,7 +75,7 @@ public:
bool catch_bp, bool throw_bp) override;
lldb::SearchFilterSP CreateExceptionSearchFilter() override;
-
+
lldb::ValueObjectSP GetExceptionObjectForThread(
lldb::ThreadSP thread_sp) override;
@@ -89,24 +93,33 @@ protected:
private:
typedef std::map<lldb_private::Address, TypeAndOrName> DynamicTypeCache;
+ typedef std::map<lldb_private::Address, VTableInfo> VTableInfoCache;
ItaniumABILanguageRuntime(Process *process)
: // Call CreateInstance instead.
- lldb_private::CPPLanguageRuntime(process), m_cxx_exception_bp_sp(),
- m_dynamic_type_map(), m_dynamic_type_map_mutex() {}
+ lldb_private::CPPLanguageRuntime(process) {}
lldb::BreakpointSP m_cxx_exception_bp_sp;
DynamicTypeCache m_dynamic_type_map;
- std::mutex m_dynamic_type_map_mutex;
+ VTableInfoCache m_vtable_info_map;
+ std::mutex m_mutex;
- TypeAndOrName GetTypeInfoFromVTableAddress(ValueObject &in_value,
- lldb::addr_t original_ptr,
- lldb::addr_t vtable_addr);
+ TypeAndOrName GetTypeInfo(ValueObject &in_value,
+ const VTableInfo &vtable_info);
TypeAndOrName GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
void SetDynamicTypeInfo(const lldb_private::Address &vtable_addr,
const TypeAndOrName &type_info);
+
+ // Check if a compiler type has a vtable.
+ //
+ // If the compiler type is a pointer or a reference, this function will check
+ // if the pointee type has a vtable, else it will check the type passed in.
+ //
+ // Returns an error if the type of the value doesn't have a vtable with an
+ // explanation why, or returns an Error::success() if the type has a vtable.
+ llvm::Error TypeHasVTable(CompilerType compiler_type);
};
} // namespace lldb_private
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 d298af92ba5e..920a5eba20ab 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
@@ -77,7 +77,7 @@ protected:
void GetIVarInformation();
private:
- static const uint32_t RW_REALIZED = (1 << 31);
+ static const uint32_t RW_REALIZED = (1u << 31);
struct objc_class_t {
ObjCLanguageRuntime::ObjCISA m_isa = 0; // The class's metaclass.
@@ -173,7 +173,8 @@ private:
}
bool Read(Process *process, lldb::addr_t addr,
- lldb::addr_t relative_method_lists_base_addr, bool, bool);
+ lldb::addr_t relative_selector_base_addr, bool is_small,
+ bool has_direct_sel);
};
struct ivar_list_t {
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 2764a2aa39fa..5d7c5f38d180 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
@@ -311,8 +311,8 @@ public:
const bool isSynthesizedAccessorStub = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
- const clang::ObjCMethodDecl::ImplementationControl impControl =
- clang::ObjCMethodDecl::None;
+ const clang::ObjCImplementationControl impControl =
+ clang::ObjCImplementationControl::None;
const bool HasRelatedResultType = false;
const bool for_expression = true;
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 80c7bd071d6b..f08f9f0f815d 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
@@ -445,7 +445,7 @@ bool AppleObjCRuntime::ExceptionBreakpointsExplainStop(
return false;
uint64_t break_site_id = stop_reason->GetValue();
- return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(
+ return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
break_site_id, m_objc_exception_bp_sp->GetID());
}
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 65f00f5e4d02..93168c23f354 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
@@ -161,7 +161,7 @@ AppleObjCRuntimeV1::CreateObjectChecker(std::string name,
" \n",
name.c_str());
assert(strformatsize < (int)sizeof(buf->contents));
- (void)strformatsize;
+ UNUSED_IF_ASSERT_DISABLED(strformatsize);
return GetTargetRef().CreateUtilityFunction(buf->contents, std::move(name),
eLanguageTypeC, exe_ctx);
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 d5357b94d68e..dc492ac0f06d 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
@@ -917,7 +917,7 @@ public:
Options *GetOptions() override { return &m_options; }
protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
std::unique_ptr<RegularExpression> regex_up;
switch (command.GetArgumentCount()) {
case 0:
@@ -929,14 +929,14 @@ protected:
result.AppendError(
"invalid argument - please provide a valid regular expression");
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ return;
}
break;
}
default: {
result.AppendError("please provide 0 or 1 arguments");
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ return;
}
}
@@ -997,11 +997,10 @@ protected:
}
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
+ return;
}
result.AppendError("current process has no Objective-C runtime loaded");
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
}
CommandOptions m_options;
@@ -1034,11 +1033,11 @@ public:
~CommandObjectMultiwordObjC_TaggedPointer_Info() override = default;
protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
if (command.GetArgumentCount() == 0) {
result.AppendError("this command requires arguments");
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ return;
}
Process *process = m_exe_ctx.GetProcessPtr();
@@ -1048,7 +1047,7 @@ protected:
if (!objc_runtime) {
result.AppendError("current process has no Objective-C runtime loaded");
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ return;
}
ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor =
@@ -1056,7 +1055,7 @@ protected:
if (!tagged_ptr_vendor) {
result.AppendError("current process has no tagged pointer support");
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ return;
}
for (size_t i = 0; i < command.GetArgumentCount(); i++) {
@@ -1071,7 +1070,7 @@ protected:
result.AppendErrorWithFormatv(
"could not convert '{0}' to a valid address\n", arg_str);
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ return;
}
if (!tagged_ptr_vendor->IsPossibleTaggedPointer(arg_addr)) {
@@ -1084,7 +1083,7 @@ protected:
result.AppendErrorWithFormatv(
"could not get class descriptor for {0:x16}\n", arg_addr);
result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ return;
}
uint64_t info_bits = 0;
@@ -1106,7 +1105,6 @@ protected:
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
}
};
@@ -1399,7 +1397,7 @@ public:
return *this;
}
- const element operator*() const {
+ element operator*() const {
if (m_index == -1) {
// TODO find a way to make this an error, but not an assert
return element();
@@ -2643,7 +2641,7 @@ static bool DoesProcessHaveSharedCache(Process &process) {
return true; // this should not happen
llvm::StringRef platform_plugin_name_sr = platform_sp->GetPluginName();
- if (platform_plugin_name_sr.endswith("-simulator"))
+ if (platform_plugin_name_sr.ends_with("-simulator"))
return false;
return true;
@@ -2733,13 +2731,13 @@ lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(ConstString name) {
llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
llvm::StringRef class_prefix("OBJC_CLASS_$_");
- if (name_strref.startswith(ivar_prefix)) {
+ if (name_strref.starts_with(ivar_prefix)) {
llvm::StringRef ivar_skipped_prefix =
name_strref.substr(ivar_prefix.size());
std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar =
ivar_skipped_prefix.split('.');
- if (class_and_ivar.first.size() && class_and_ivar.second.size()) {
+ if (!class_and_ivar.first.empty() && !class_and_ivar.second.empty()) {
const ConstString class_name_cs(class_and_ivar.first);
ClassDescriptorSP descriptor =
ObjCLanguageRuntime::GetClassDescriptorFromClassName(class_name_cs);
@@ -2766,7 +2764,7 @@ lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(ConstString name) {
ivar_func);
}
}
- } else if (name_strref.startswith(class_prefix)) {
+ } else if (name_strref.starts_with(class_prefix)) {
llvm::StringRef class_skipped_prefix =
name_strref.substr(class_prefix.size());
const ConstString class_name_cs(class_skipped_prefix);
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 678865ecd918..c9d0b3a907b5 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
@@ -65,12 +65,12 @@ public:
return ObjCRuntimeVersions::eAppleObjC_V2;
}
- size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
+ size_t GetByteOffsetForIvar(CompilerType &parent_ast_type,
const char *ivar_name) override;
void UpdateISAToDescriptorMapIfNeeded() override;
- ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override;
+ ClassDescriptorSP GetClassDescriptor(ValueObject &valobj) override;
ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override;
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 940e66afa0c0..2b8adeae10d1 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
@@ -13,7 +13,6 @@
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
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 2cc5319c84bb..ca582cb1d5a4 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
@@ -81,13 +81,13 @@ AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
clang::QualType AppleObjCTypeEncodingParser::BuildStruct(
TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, _C_STRUCT_B, _C_STRUCT_E,
- clang::TTK_Struct);
+ llvm::to_underlying(clang::TagTypeKind::Struct));
}
clang::QualType AppleObjCTypeEncodingParser::BuildUnion(
TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, _C_UNION_B, _C_UNION_E,
- clang::TTK_Union);
+ llvm::to_underlying(clang::TagTypeKind::Union));
}
clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
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 547a1f6db976..4093cbdd955f 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
@@ -333,7 +333,7 @@ AppleThreadPlanStepThroughDirectDispatch::DoPlanExplainsStop(Event *event_ptr) {
if (site_sp->IsBreakpointAtThisSite(break_sp->GetID())) {
// If we aren't the only one with a breakpoint on this site, then we
// should just stop and return control to the user.
- if (site_sp->GetNumberOfOwners() > 1) {
+ if (site_sp->GetNumberOfConstituents() > 1) {
SetPlanComplete(true);
return false;
}
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 214642f654e2..ba52444f0c2f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -10,7 +10,6 @@
#include "ObjCLanguageRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
-#include "lldb/Core/MappedHash.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/ValueObject.h"
@@ -140,17 +139,10 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
if (!module_sp)
return TypeSP();
- const bool exact_match = true;
- const uint32_t max_matches = UINT32_MAX;
- TypeList types;
-
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_sp->FindTypes(name, exact_match, max_matches, searched_symbol_files,
- types);
-
- for (uint32_t i = 0; i < types.GetSize(); ++i) {
- TypeSP type_sp(types.GetTypeAtIndex(i));
-
+ TypeQuery query(name.GetStringRef(), TypeQueryOptions::e_exact_match);
+ TypeResults results;
+ module_sp->FindTypes(query, results);
+ for (const TypeSP &type_sp : results.GetTypeMap().Types()) {
if (TypeSystemClang::IsObjCObjectOrInterfaceType(
type_sp->GetForwardCompilerType())) {
if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) {
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 957ecc223405..7aa5b8d81890 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
@@ -10,7 +10,6 @@
#if defined(_WIN32) || defined(__ANDROID__)
// Defines from ar, missing on Windows
-#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
@@ -32,9 +31,11 @@ typedef struct ar_hdr {
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/Object/Archive.h"
#include "llvm/Support/MemoryBuffer.h"
using namespace lldb;
@@ -49,158 +50,19 @@ ObjectContainerBSDArchive::Object::Object() : ar_name() {}
void ObjectContainerBSDArchive::Object::Clear() {
ar_name.Clear();
modification_time = 0;
- uid = 0;
- gid = 0;
- mode = 0;
size = 0;
file_offset = 0;
file_size = 0;
}
-lldb::offset_t ObjectContainerBSDArchive::Object::ExtractFromThin(
- const DataExtractor &data, lldb::offset_t offset,
- llvm::StringRef stringTable) {
- size_t ar_name_len = 0;
- std::string str;
- char *err;
-
- // File header
- //
- // The common format is as follows.
- //
- // Offset Length Name Format
- // 0 16 File name ASCII right padded with spaces (no spaces
- // allowed in file name)
- // 16 12 File mod Decimal as cstring right padded with
- // spaces
- // 28 6 Owner ID Decimal as cstring right padded with
- // spaces
- // 34 6 Group ID Decimal as cstring right padded with
- // spaces
- // 40 8 File mode Octal as cstring right padded with
- // spaces
- // 48 10 File byte size Decimal as cstring right padded with
- // spaces
- // 58 2 File magic 0x60 0x0A
-
- // Make sure there is enough data for the file header and bail if not
- if (!data.ValidOffsetForDataOfSize(offset, 60))
- return LLDB_INVALID_OFFSET;
-
- str.assign((const char *)data.GetData(&offset, 16), 16);
- if (!(llvm::StringRef(str).startswith("//") || stringTable.empty())) {
- // Strip off any trailing spaces.
- const size_t last_pos = str.find_last_not_of(' ');
- if (last_pos != std::string::npos) {
- if (last_pos + 1 < 16)
- str.erase(last_pos + 1);
- }
- int start = strtoul(str.c_str() + 1, &err, 10);
- int end = stringTable.find('\n', start);
- str.assign(stringTable.data() + start, end - start - 1);
- ar_name.SetCString(str.c_str());
- }
-
- str.assign((const char *)data.GetData(&offset, 12), 12);
- modification_time = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 6), 6);
- uid = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 6), 6);
- gid = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 8), 8);
- mode = strtoul(str.c_str(), &err, 8);
-
- str.assign((const char *)data.GetData(&offset, 10), 10);
- size = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 2), 2);
- if (str == ARFMAG) {
- file_offset = offset;
- file_size = size - ar_name_len;
- return offset;
- }
- return LLDB_INVALID_OFFSET;
-}
-
-lldb::offset_t
-ObjectContainerBSDArchive::Object::Extract(const DataExtractor &data,
- lldb::offset_t offset) {
- size_t ar_name_len = 0;
- std::string str;
- char *err;
-
- // File header
- //
- // The common format is as follows.
- //
- // Offset Length Name Format
- // 0 16 File name ASCII right padded with spaces (no spaces
- // allowed in file name)
- // 16 12 File mod Decimal as cstring right padded with
- // spaces
- // 28 6 Owner ID Decimal as cstring right padded with
- // spaces
- // 34 6 Group ID Decimal as cstring right padded with
- // spaces
- // 40 8 File mode Octal as cstring right padded with
- // spaces
- // 48 10 File byte size Decimal as cstring right padded with
- // spaces
- // 58 2 File magic 0x60 0x0A
-
- // Make sure there is enough data for the file header and bail if not
- if (!data.ValidOffsetForDataOfSize(offset, 60))
- return LLDB_INVALID_OFFSET;
-
- str.assign((const char *)data.GetData(&offset, 16), 16);
- if (llvm::StringRef(str).startswith("#1/")) {
- // If the name is longer than 16 bytes, or contains an embedded space then
- // it will use this format where the length of the name is here and the
- // name characters are after this header.
- ar_name_len = strtoul(str.c_str() + 3, &err, 10);
- } else {
- // Strip off any trailing spaces.
- const size_t last_pos = str.find_last_not_of(' ');
- if (last_pos != std::string::npos) {
- if (last_pos + 1 < 16)
- str.erase(last_pos + 1);
- }
- ar_name.SetCString(str.c_str());
- }
-
- str.assign((const char *)data.GetData(&offset, 12), 12);
- modification_time = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 6), 6);
- uid = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 6), 6);
- gid = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 8), 8);
- mode = strtoul(str.c_str(), &err, 8);
-
- str.assign((const char *)data.GetData(&offset, 10), 10);
- size = strtoul(str.c_str(), &err, 10);
-
- str.assign((const char *)data.GetData(&offset, 2), 2);
- if (str == ARFMAG) {
- if (ar_name_len > 0) {
- const void *ar_name_ptr = data.GetData(&offset, ar_name_len);
- // Make sure there was enough data for the string value and bail if not
- if (ar_name_ptr == nullptr)
- return LLDB_INVALID_OFFSET;
- str.assign((const char *)ar_name_ptr, ar_name_len);
- ar_name.SetCString(str.c_str());
- }
- file_offset = offset;
- file_size = size - ar_name_len;
- return offset;
- }
- return LLDB_INVALID_OFFSET;
+void ObjectContainerBSDArchive::Object::Dump() const {
+ printf("name = \"%s\"\n", ar_name.GetCString());
+ printf("mtime = 0x%8.8" PRIx32 "\n", modification_time);
+ printf("size = 0x%8.8" PRIx32 " (%" PRIu32 ")\n", size, size);
+ printf("file_offset = 0x%16.16" PRIx64 " (%" PRIu64 ")\n", file_offset,
+ file_offset);
+ printf("file_size = 0x%16.16" PRIx64 " (%" PRIu64 ")\n\n", file_size,
+ file_size);
}
ObjectContainerBSDArchive::Archive::Archive(const lldb_private::ArchSpec &arch,
@@ -211,72 +73,79 @@ 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), m_archive_type(archive_type) {}
+Log *l = GetLog(LLDBLog::Object);
ObjectContainerBSDArchive::Archive::~Archive() = default;
size_t ObjectContainerBSDArchive::Archive::ParseObjects() {
DataExtractor &data = m_data;
- std::string str;
- lldb::offset_t offset = 0;
- str.assign((const char *)data.GetData(&offset, SARMAG), SARMAG);
- if (str == ARMAG) {
- Object obj;
- do {
- offset = obj.Extract(data, offset);
- if (offset == LLDB_INVALID_OFFSET)
- break;
- size_t obj_idx = m_objects.size();
- m_objects.push_back(obj);
- // Insert all of the C strings out of order for now...
- m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
- offset += obj.file_size;
- obj.Clear();
- } while (data.ValidOffset(offset));
-
- // Now sort all of the object name pointers
- m_object_name_to_index_map.Sort();
- } else if (str == ThinArchiveMagic) {
- Object obj;
- size_t obj_idx;
-
- // Retrieve symbol table
- offset = obj.ExtractFromThin(data, offset, "");
- if (offset == LLDB_INVALID_OFFSET)
- return m_objects.size();
- obj_idx = m_objects.size();
- m_objects.push_back(obj);
- // Insert all of the C strings out of order for now...
- m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
- offset += obj.file_size;
- obj.Clear();
- // Retrieve string table
- offset = obj.ExtractFromThin(data, offset, "");
- if (offset == LLDB_INVALID_OFFSET)
- return m_objects.size();
- obj_idx = m_objects.size();
- m_objects.push_back(obj);
- // Insert all of the C strings out of order for now...
- m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
- // Extract string table
- llvm::StringRef strtab((const char *)data.GetData(&offset, obj.size),
- obj.size);
+ std::unique_ptr<llvm::MemoryBuffer> mem_buffer =
+ llvm::MemoryBuffer::getMemBuffer(
+ llvm::StringRef((const char *)data.GetDataStart(),
+ data.GetByteSize()),
+ llvm::StringRef(),
+ /*RequiresNullTerminator=*/false);
+
+ auto exp_ar = llvm::object::Archive::create(mem_buffer->getMemBufferRef());
+ if (!exp_ar) {
+ LLDB_LOG_ERROR(l, exp_ar.takeError(), "failed to create archive: {0}");
+ return 0;
+ }
+ auto llvm_archive = std::move(exp_ar.get());
+
+ llvm::Error iter_err = llvm::Error::success();
+ Object obj;
+ for (const auto &child: llvm_archive->children(iter_err)) {
obj.Clear();
+ auto exp_name = child.getName();
+ if (exp_name) {
+ obj.ar_name = ConstString(exp_name.get());
+ } else {
+ LLDB_LOG_ERROR(l, exp_name.takeError(),
+ "failed to get archive object name: {0}");
+ continue;
+ }
+
+ auto exp_mtime = child.getLastModified();
+ if (exp_mtime) {
+ obj.modification_time =
+ std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::time_point_cast<std::chrono::seconds>(
+ exp_mtime.get()).time_since_epoch()).count();
+ } else {
+ LLDB_LOG_ERROR(l, exp_mtime.takeError(),
+ "failed to get archive object time: {0}");
+ continue;
+ }
- // Retrieve object files
- do {
- offset = obj.ExtractFromThin(data, offset, strtab);
- if (offset == LLDB_INVALID_OFFSET)
- break;
- obj_idx = m_objects.size();
- m_objects.push_back(obj);
- // Insert all of the C strings out of order for now...
- m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
- obj.Clear();
- } while (data.ValidOffset(offset));
-
- // Now sort all of the object name pointers
- m_object_name_to_index_map.Sort();
+ auto exp_size = child.getRawSize();
+ if (exp_size) {
+ obj.size = exp_size.get();
+ } else {
+ LLDB_LOG_ERROR(l, exp_size.takeError(),
+ "failed to get archive object size: {0}");
+ continue;
+ }
+
+ obj.file_offset = child.getDataOffset();
+
+ auto exp_file_size = child.getSize();
+ if (exp_file_size) {
+ obj.file_size = exp_file_size.get();
+ } else {
+ LLDB_LOG_ERROR(l, exp_file_size.takeError(),
+ "failed to get archive object file size: {0}");
+ continue;
+ }
+ m_object_name_to_index_map.Append(obj.ar_name, m_objects.size());
+ m_objects.push_back(obj);
+ }
+ if (iter_err) {
+ LLDB_LOG_ERROR(l, std::move(iter_err),
+ "failed to iterate over archive objects: {0}");
}
+ // Now sort all of the object name pointers
+ m_object_name_to_index_map.Sort();
return m_objects.size();
}
@@ -462,20 +331,21 @@ ObjectContainer *ObjectContainerBSDArchive::CreateInstance(
ArchiveType
ObjectContainerBSDArchive::MagicBytesMatch(const DataExtractor &data) {
uint32_t offset = 0;
- const char *armag = (const char *)data.PeekData(offset, sizeof(ar_hdr));
+ const char *armag = (const char *)data.PeekData(offset,
+ sizeof(ar_hdr) + SARMAG);
if (armag == nullptr)
return ArchiveType::Invalid;
- if (::strncmp(armag, ARMAG, SARMAG) == 0) {
- armag += offsetof(struct ar_hdr, ar_fmag) + SARMAG;
- if (strncmp(armag, ARFMAG, 2) == 0)
- return ArchiveType::Archive;
- } else if (::strncmp(armag, ThinArchiveMagic, strlen(ThinArchiveMagic)) ==
- 0) {
- armag += offsetof(struct ar_hdr, ar_fmag) + strlen(ThinArchiveMagic);
- if (strncmp(armag, ARFMAG, 2) == 0) {
- return ArchiveType::ThinArchive;
- }
- }
+ ArchiveType result = ArchiveType::Invalid;
+ if (strncmp(armag, ArchiveMagic, SARMAG) == 0)
+ result = ArchiveType::Archive;
+ else if (strncmp(armag, ThinArchiveMagic, SARMAG) == 0)
+ result = ArchiveType::ThinArchive;
+ else
+ return ArchiveType::Invalid;
+
+ armag += offsetof(struct ar_hdr, ar_fmag) + SARMAG;
+ if (strncmp(armag, ARFMAG, 2) == 0)
+ return result;
return ArchiveType::Invalid;
}
@@ -540,7 +410,8 @@ ObjectFileSP ObjectContainerBSDArchive::GetObjectFile(const FileSpec *file) {
std::shared_ptr<DataBuffer> child_data_sp =
FileSystem::Instance().CreateDataBuffer(child, file_size,
file_offset);
- if (child_data_sp->GetByteSize() != object->file_size)
+ if (!child_data_sp ||
+ child_data_sp->GetByteSize() != object->file_size)
return ObjectFileSP();
lldb::offset_t data_offset = 0;
return ObjectFile::FindPlugin(
@@ -622,7 +493,7 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications(
std::chrono::seconds(object->modification_time));
spec.GetObjectName() = object->ar_name;
spec.SetObjectOffset(object_file_offset);
- spec.SetObjectSize(file_size - object_file_offset);
+ spec.SetObjectSize(object->file_size);
spec.GetObjectModificationTime() = object_mod_time;
}
}
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 1e2ffce3e5e2..fbecd1d27063 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
@@ -93,15 +93,6 @@ protected:
/// Object modification time in the archive.
uint32_t modification_time = 0;
- /// Object user id in the archive.
- uint16_t uid = 0;
-
- /// Object group id in the archive.
- uint16_t gid = 0;
-
- /// Object octal file permissions in the archive.
- uint16_t mode = 0;
-
/// Object size in bytes in the archive.
uint32_t size = 0;
@@ -110,6 +101,8 @@ protected:
/// Length of the object data.
lldb::offset_t file_size = 0;
+
+ void Dump() const;
};
class Archive {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp
index 4f9661eb0cdf..2dc71d85777c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp
@@ -158,7 +158,7 @@ ParseFileset(DataExtractor &data, mach_header header,
if (lc.cmd == LC_FILESET_ENTRY) {
fileset_entry_command entry;
data.CopyData(load_cmd_offset, sizeof(fileset_entry_command), &entry);
- lldb::offset_t entry_id_offset = load_cmd_offset + entry.entry_id;
+ lldb::offset_t entry_id_offset = load_cmd_offset + entry.entry_id.offset;
const char *id = data.GetCStr(&entry_id_offset);
entries.emplace_back(entry.vmaddr + slide, entry.fileoff,
std::string(id));
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index b0afe0394622..d40f87b1a7b4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
+#include "lldb/lldb-defines.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Endian.h"
@@ -119,7 +120,7 @@ static UUID parseModuleId(llvm::Triple::OSType os, llvm::StringRef str) {
uint32_t age;
bool success = to_integer(age_str, age, 16);
assert(success);
- (void)success;
+ UNUSED_IF_ASSERT_DISABLED(success);
data.age = age;
// On non-windows, the age field should always be zero, so we don't include to
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp
index 03c454bf3efa..a7ad5d27b237 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp
@@ -271,9 +271,9 @@ void ObjectFileCOFF::ParseSymtab(lldb_private::Symtab &symtab) {
const auto COFFSymRef = m_object->getCOFFSymbol(SymRef);
Expected<StringRef> NameOrErr = SymRef.getName();
- if (auto error = NameOrErr.takeError()) {
- LLDB_LOG(log, "ObjectFileCOFF: failed to get symbol name: {0}",
- llvm::fmt_consume(std::move(error)));
+ if (!NameOrErr) {
+ LLDB_LOG_ERROR(log, NameOrErr.takeError(),
+ "ObjectFileCOFF: failed to get symbol name: {0}");
continue;
}
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 700af84a14c0..43ab87f08e19 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -935,6 +935,16 @@ lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
}
Address ObjectFileELF::GetBaseAddress() {
+ if (GetType() == ObjectFile::eTypeObjectFile) {
+ for (SectionHeaderCollIter I = std::next(m_section_headers.begin());
+ I != m_section_headers.end(); ++I) {
+ const ELFSectionHeaderInfo &header = *I;
+ if (header.sh_flags & SHF_ALLOC)
+ return Address(GetSectionList()->FindSectionByID(SectionIndex(I)), 0);
+ }
+ return LLDB_INVALID_ADDRESS;
+ }
+
for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
const ELFProgramHeader &H = EnumPHdr.value();
if (H.p_type != PT_LOAD)
@@ -1679,6 +1689,7 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
.Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
.Case(".gosymtab", eSectionTypeGoSymtab)
.Case(".text", eSectionTypeCode)
+ .Case(".swift_ast", eSectionTypeSwiftModules)
.Default(eSectionTypeOther);
}
@@ -1763,7 +1774,12 @@ class VMAddressProvider {
VMRange GetVMRange(const ELFSectionHeader &H) {
addr_t Address = H.sh_addr;
addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0;
- if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
+
+ // When this is a debug file for relocatable file, the address is all zero
+ // and thus needs to use accumulate method
+ if ((ObjectType == ObjectFile::Type::eTypeObjectFile ||
+ (ObjectType == ObjectFile::Type::eTypeDebugInfo && H.sh_addr == 0)) &&
+ Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
NextVMAddress =
llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1));
Address = NextVMAddress;
@@ -3453,10 +3469,28 @@ ObjectFile::Strata ObjectFileELF::CalculateStrata() {
case llvm::ELF::ET_EXEC:
// 2 - Executable file
- // TODO: is there any way to detect that an executable is a kernel
- // related executable by inspecting the program headers, section headers,
- // symbols, or any other flag bits???
- return eStrataUser;
+ {
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ static ConstString loader_section_name(".interp");
+ SectionSP loader_section =
+ section_list->FindSectionByName(loader_section_name);
+ if (loader_section) {
+ char buffer[256];
+ size_t read_size =
+ ReadSectionData(loader_section.get(), 0, buffer, sizeof(buffer));
+
+ // We compare the content of .interp section
+ // It will contains \0 when counting read_size, so the size needs to
+ // decrease by one
+ llvm::StringRef loader_name(buffer, read_size - 1);
+ llvm::StringRef freebsd_kernel_loader_name("/red/herring");
+ if (loader_name.equals(freebsd_kernel_loader_name))
+ return eStrataKernel;
+ }
+ }
+ return eStrataUser;
+ }
case llvm::ELF::ET_DYN:
// 3 - Shared object file
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index c396cb061c01..50d1b563f469 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -8,6 +8,7 @@
#include "MinidumpFileBuilder.h"
+#include "Plugins/Process/minidump/RegisterContextMinidump_ARM64.h"
#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h"
#include "lldb/Core/Module.h"
@@ -293,7 +294,7 @@ Status MinidumpFileBuilder::AddModuleList(Target &target) {
}
uint16_t read_register_u16_raw(RegisterContext *reg_ctx,
- const std::string &reg_name) {
+ llvm::StringRef reg_name) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
if (!reg_info)
return 0;
@@ -305,7 +306,7 @@ uint16_t read_register_u16_raw(RegisterContext *reg_ctx,
}
uint32_t read_register_u32_raw(RegisterContext *reg_ctx,
- const std::string &reg_name) {
+ llvm::StringRef reg_name) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
if (!reg_info)
return 0;
@@ -317,7 +318,7 @@ uint32_t read_register_u32_raw(RegisterContext *reg_ctx,
}
uint64_t read_register_u64_raw(RegisterContext *reg_ctx,
- const std::string &reg_name) {
+ llvm::StringRef reg_name) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
if (!reg_info)
return 0;
@@ -329,25 +330,42 @@ uint64_t read_register_u64_raw(RegisterContext *reg_ctx,
}
llvm::support::ulittle16_t read_register_u16(RegisterContext *reg_ctx,
- const std::string &reg_name) {
+ llvm::StringRef reg_name) {
return static_cast<llvm::support::ulittle16_t>(
read_register_u16_raw(reg_ctx, reg_name));
}
llvm::support::ulittle32_t read_register_u32(RegisterContext *reg_ctx,
- const std::string &reg_name) {
+ llvm::StringRef reg_name) {
return static_cast<llvm::support::ulittle32_t>(
read_register_u32_raw(reg_ctx, reg_name));
}
llvm::support::ulittle64_t read_register_u64(RegisterContext *reg_ctx,
- const std::string &reg_name) {
+ llvm::StringRef reg_name) {
return static_cast<llvm::support::ulittle64_t>(
read_register_u64_raw(reg_ctx, reg_name));
}
+void read_register_u128(RegisterContext *reg_ctx, llvm::StringRef reg_name,
+ uint8_t *dst) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
+ if (reg_info) {
+ lldb_private::RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ Status error;
+ uint32_t bytes_copied = reg_value.GetAsMemoryData(
+ *reg_info, dst, 16, lldb::ByteOrder::eByteOrderLittle, error);
+ if (bytes_copied == 16)
+ return;
+ }
+ }
+ // If anything goes wrong, then zero out the register value.
+ memset(dst, 0, 16);
+}
+
lldb_private::minidump::MinidumpContext_x86_64
-GetThreadContext_64(RegisterContext *reg_ctx) {
+GetThreadContext_x86_64(RegisterContext *reg_ctx) {
lldb_private::minidump::MinidumpContext_x86_64 thread_context = {};
thread_context.p1_home = {};
thread_context.context_flags = static_cast<uint32_t>(
@@ -381,6 +399,71 @@ GetThreadContext_64(RegisterContext *reg_ctx) {
return thread_context;
}
+minidump::RegisterContextMinidump_ARM64::Context
+GetThreadContext_ARM64(RegisterContext *reg_ctx) {
+ minidump::RegisterContextMinidump_ARM64::Context thread_context = {};
+ thread_context.context_flags = static_cast<uint32_t>(
+ minidump::RegisterContextMinidump_ARM64::Flags::ARM64_Flag |
+ minidump::RegisterContextMinidump_ARM64::Flags::Integer |
+ minidump::RegisterContextMinidump_ARM64::Flags::FloatingPoint);
+ char reg_name[16];
+ for (uint32_t i = 0; i < 31; ++i) {
+ snprintf(reg_name, sizeof(reg_name), "x%u", i);
+ thread_context.x[i] = read_register_u64(reg_ctx, reg_name);
+ }
+ // Work around a bug in debugserver where "sp" on arm64 doesn't have the alt
+ // name set to "x31"
+ thread_context.x[31] = read_register_u64(reg_ctx, "sp");
+ thread_context.pc = read_register_u64(reg_ctx, "pc");
+ thread_context.cpsr = read_register_u32(reg_ctx, "cpsr");
+ thread_context.fpsr = read_register_u32(reg_ctx, "fpsr");
+ thread_context.fpcr = read_register_u32(reg_ctx, "fpcr");
+ for (uint32_t i = 0; i < 32; ++i) {
+ snprintf(reg_name, sizeof(reg_name), "v%u", i);
+ read_register_u128(reg_ctx, reg_name, &thread_context.v[i * 16]);
+ }
+ return thread_context;
+}
+
+class ArchThreadContexts {
+ llvm::Triple::ArchType m_arch;
+ union {
+ lldb_private::minidump::MinidumpContext_x86_64 x86_64;
+ lldb_private::minidump::RegisterContextMinidump_ARM64::Context arm64;
+ };
+
+public:
+ ArchThreadContexts(llvm::Triple::ArchType arch) : m_arch(arch) {}
+
+ bool prepareRegisterContext(RegisterContext *reg_ctx) {
+ switch (m_arch) {
+ case llvm::Triple::ArchType::x86_64:
+ x86_64 = GetThreadContext_x86_64(reg_ctx);
+ return true;
+ case llvm::Triple::ArchType::aarch64:
+ arm64 = GetThreadContext_ARM64(reg_ctx);
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ const void *data() const { return &x86_64; }
+
+ size_t size() const {
+ switch (m_arch) {
+ case llvm::Triple::ArchType::x86_64:
+ return sizeof(x86_64);
+ case llvm::Triple::ArchType::aarch64:
+ return sizeof(arm64);
+ default:
+ break;
+ }
+ return 0;
+ }
+};
+
// Function returns start and size of the memory region that contains
// memory location pointed to by the current stack pointer.
llvm::Expected<std::pair<addr_t, addr_t>>
@@ -434,11 +517,20 @@ Status MinidumpFileBuilder::AddThreadList(const lldb::ProcessSP &process_sp) {
return error;
}
RegisterContext *reg_ctx = reg_ctx_sp.get();
- auto thread_context = GetThreadContext_64(reg_ctx);
- uint64_t rsp = read_register_u64_raw(reg_ctx, "rsp");
- auto expected_address_range = findStackHelper(process_sp, rsp);
+ Target &target = process_sp->GetTarget();
+ const ArchSpec &arch = target.GetArchitecture();
+ ArchThreadContexts thread_context(arch.GetMachine());
+ if (!thread_context.prepareRegisterContext(reg_ctx)) {
+ error.SetErrorStringWithFormat(
+ "architecture %s not supported.",
+ arch.GetTriple().getArchName().str().c_str());
+ return error;
+ }
+ uint64_t sp = reg_ctx->GetSP();
+ auto expected_address_range = findStackHelper(process_sp, sp);
if (!expected_address_range) {
+ consumeError(expected_address_range.takeError());
error.SetErrorString("Unable to get the stack address.");
return error;
}
@@ -468,13 +560,13 @@ Status MinidumpFileBuilder::AddThreadList(const lldb::ProcessSP &process_sp) {
LocationDescriptor thread_context_memory_locator;
thread_context_memory_locator.DataSize =
- static_cast<llvm::support::ulittle32_t>(sizeof(thread_context));
+ static_cast<llvm::support::ulittle32_t>(thread_context.size());
thread_context_memory_locator.RVA = static_cast<llvm::support::ulittle32_t>(
size_before + thread_stream_size + helper_data.GetByteSize());
+ // Cache thie thread context memory so we can reuse for exceptions.
+ m_tid_to_reg_ctx[thread_sp->GetID()] = thread_context_memory_locator;
- helper_data.AppendData(
- &thread_context,
- sizeof(lldb_private::minidump::MinidumpContext_x86_64));
+ helper_data.AppendData(thread_context.data(), thread_context.size());
llvm::minidump::Thread t;
t.ThreadId = static_cast<llvm::support::ulittle32_t>(thread_sp->GetID());
@@ -492,108 +584,76 @@ Status MinidumpFileBuilder::AddThreadList(const lldb::ProcessSP &process_sp) {
return Status();
}
-Status MinidumpFileBuilder::AddException(const lldb::ProcessSP &process_sp) {
- Status error;
+void MinidumpFileBuilder::AddExceptions(const lldb::ProcessSP &process_sp) {
lldb_private::ThreadList thread_list = process_sp->GetThreadList();
const uint32_t num_threads = thread_list.GetSize();
- uint32_t stop_reason_thread_idx = 0;
- for (stop_reason_thread_idx = 0; stop_reason_thread_idx < num_threads;
- ++stop_reason_thread_idx) {
- ThreadSP thread_sp(thread_list.GetThreadAtIndex(stop_reason_thread_idx));
+ for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
+ ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
-
- if (stop_info_sp && stop_info_sp->IsValid())
- break;
- }
-
- if (stop_reason_thread_idx == num_threads) {
- error.SetErrorString("No stop reason thread found.");
- return error;
+ bool add_exception = false;
+ if (stop_info_sp) {
+ switch (stop_info_sp->GetStopReason()) {
+ case eStopReasonSignal:
+ case eStopReasonException:
+ add_exception = true;
+ break;
+ default:
+ break;
+ }
+ }
+ if (add_exception) {
+ constexpr size_t minidump_exception_size =
+ sizeof(llvm::minidump::ExceptionStream);
+ AddDirectory(StreamType::Exception, minidump_exception_size);
+ StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
+ RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
+ Exception exp_record = {};
+ exp_record.ExceptionCode =
+ static_cast<llvm::support::ulittle32_t>(stop_info_sp->GetValue());
+ exp_record.ExceptionFlags = static_cast<llvm::support::ulittle32_t>(0);
+ exp_record.ExceptionRecord = static_cast<llvm::support::ulittle64_t>(0);
+ exp_record.ExceptionAddress = reg_ctx_sp->GetPC();
+ exp_record.NumberParameters = static_cast<llvm::support::ulittle32_t>(0);
+ exp_record.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0);
+ // exp_record.ExceptionInformation;
+
+ ExceptionStream exp_stream;
+ exp_stream.ThreadId =
+ static_cast<llvm::support::ulittle32_t>(thread_sp->GetID());
+ exp_stream.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0);
+ exp_stream.ExceptionRecord = exp_record;
+ auto Iter = m_tid_to_reg_ctx.find(thread_sp->GetID());
+ if (Iter != m_tid_to_reg_ctx.end()) {
+ exp_stream.ThreadContext = Iter->second;
+ } else {
+ exp_stream.ThreadContext.DataSize = 0;
+ exp_stream.ThreadContext.RVA = 0;
+ }
+ m_data.AppendData(&exp_stream, minidump_exception_size);
+ }
}
-
- constexpr size_t minidump_exception_size =
- sizeof(llvm::minidump::ExceptionStream);
- AddDirectory(StreamType::Exception, minidump_exception_size);
- size_t size_before = GetCurrentDataEndOffset();
-
- ThreadSP thread_sp(thread_list.GetThreadAtIndex(stop_reason_thread_idx));
- RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
- RegisterContext *reg_ctx = reg_ctx_sp.get();
- auto thread_context = GetThreadContext_64(reg_ctx);
- StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
-
- DataBufferHeap helper_data;
-
- LocationDescriptor thread_context_memory_locator;
- thread_context_memory_locator.DataSize =
- static_cast<llvm::support::ulittle32_t>(sizeof(thread_context));
- thread_context_memory_locator.RVA = static_cast<llvm::support::ulittle32_t>(
- size_before + minidump_exception_size + helper_data.GetByteSize());
-
- helper_data.AppendData(
- &thread_context, sizeof(lldb_private::minidump::MinidumpContext_x86_64));
-
- Exception exp_record = {};
- exp_record.ExceptionCode =
- static_cast<llvm::support::ulittle32_t>(stop_info_sp->GetValue());
- exp_record.ExceptionFlags = static_cast<llvm::support::ulittle32_t>(0);
- exp_record.ExceptionRecord = static_cast<llvm::support::ulittle64_t>(0);
- exp_record.ExceptionAddress = read_register_u64(reg_ctx, "rip");
- exp_record.NumberParameters = static_cast<llvm::support::ulittle32_t>(0);
- exp_record.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0);
- // exp_record.ExceptionInformation;
-
- ExceptionStream exp_stream;
- exp_stream.ThreadId =
- static_cast<llvm::support::ulittle32_t>(thread_sp->GetID());
- exp_stream.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0);
- exp_stream.ExceptionRecord = exp_record;
- exp_stream.ThreadContext = thread_context_memory_locator;
-
- m_data.AppendData(&exp_stream, minidump_exception_size);
- m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize());
- return error;
}
lldb_private::Status
-MinidumpFileBuilder::AddMemoryList(const lldb::ProcessSP &process_sp) {
+MinidumpFileBuilder::AddMemoryList(const lldb::ProcessSP &process_sp,
+ lldb::SaveCoreStyle core_style) {
Status error;
-
+ Process::CoreFileMemoryRanges core_ranges;
+ error = process_sp->CalculateCoreFileSaveRanges(core_style, core_ranges);
if (error.Fail()) {
error.SetErrorString("Process doesn't support getting memory region info.");
return error;
}
- // Get interesting addresses
- std::vector<size_t> interesting_addresses;
- auto thread_list = process_sp->GetThreadList();
- for (size_t i = 0; i < thread_list.GetSize(); ++i) {
- ThreadSP thread_sp(thread_list.GetThreadAtIndex(i));
- RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- interesting_addresses.push_back(read_register_u64(reg_ctx, "rsp"));
- interesting_addresses.push_back(read_register_u64(reg_ctx, "rip"));
- }
-
DataBufferHeap helper_data;
std::vector<MemoryDescriptor> mem_descriptors;
-
- std::set<addr_t> visited_region_base_addresses;
- for (size_t interesting_address : interesting_addresses) {
- MemoryRegionInfo range_info;
- error = process_sp->GetMemoryRegionInfo(interesting_address, range_info);
- // Skip failed memory region requests or any regions with no permissions.
- if (error.Fail() || range_info.GetLLDBPermissions() == 0)
- continue;
- const addr_t addr = range_info.GetRange().GetRangeBase();
- // Skip any regions we have already saved out.
- if (visited_region_base_addresses.insert(addr).second == false)
- continue;
- const addr_t size = range_info.GetRange().GetByteSize();
- if (size == 0)
+ for (const auto &core_range : core_ranges) {
+ // Skip empty memory regions or any regions with no permissions.
+ if (core_range.range.empty() || core_range.lldb_permissions == 0)
continue;
+ const addr_t addr = core_range.range.start();
+ const addr_t size = core_range.range.size();
auto data_up = std::make_unique<DataBufferHeap>(size, 0);
const size_t bytes_read =
process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
index f4017fb66384..b2e984191983 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
@@ -17,6 +17,7 @@
#define LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H
#include <cstddef>
+#include <map>
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -59,12 +60,11 @@ public:
// at the moment of core saving. Contains information about thread
// contexts.
lldb_private::Status AddThreadList(const lldb::ProcessSP &process_sp);
- // Add Exception stream, this contains information about the exception
- // that stopped the process. In case no thread made exception it return
- // failed status.
- lldb_private::Status AddException(const lldb::ProcessSP &process_sp);
+ // Add Exception streams for any threads that stopped with exceptions.
+ void AddExceptions(const lldb::ProcessSP &process_sp);
// Add MemoryList stream, containing dumps of important memory segments
- lldb_private::Status AddMemoryList(const lldb::ProcessSP &process_sp);
+ lldb_private::Status AddMemoryList(const lldb::ProcessSP &process_sp,
+ lldb::SaveCoreStyle core_style);
// Add MiscInfo stream, mainly providing ProcessId
void AddMiscInfo(const lldb::ProcessSP &process_sp);
// Add informative files about a Linux process
@@ -87,6 +87,11 @@ private:
// Main data buffer consisting of data without the minidump header and
// directories
lldb_private::DataBufferHeap m_data;
+
+ // More that one place can mention the register thread context locations,
+ // so when we emit the thread contents, remember where it is so we don't have
+ // to duplicate it in the exception data.
+ std::map<lldb::tid_t, llvm::minidump::LocationDescriptor> m_tid_to_reg_ctx;
};
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
index 17b37afe557d..fe609c7f3d20 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
@@ -57,10 +57,9 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
const lldb_private::FileSpec &outfile,
lldb::SaveCoreStyle &core_style,
lldb_private::Status &error) {
- if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
- error.SetErrorString("Only stack minidumps supported yet.");
- return false;
- }
+ // Set default core style if it isn't set.
+ if (core_style == SaveCoreStyle::eSaveCoreUnspecified)
+ core_style = SaveCoreStyle::eSaveCoreStackOnly;
if (!process_sp)
return false;
@@ -79,19 +78,16 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
builder.AddMiscInfo(process_sp);
- if (target.GetArchitecture().GetMachine() == llvm::Triple::ArchType::x86_64) {
- error = builder.AddThreadList(process_sp);
- if (error.Fail())
- return false;
+ error = builder.AddThreadList(process_sp);
+ if (error.Fail())
+ return false;
- error = builder.AddException(process_sp);
- if (error.Fail())
- return false;
+ // Add any exceptions but only if there are any in any threads.
+ builder.AddExceptions(process_sp);
- error = builder.AddMemoryList(process_sp);
- if (error.Fail())
- return false;
- }
+ error = builder.AddMemoryList(process_sp, core_style);
+ if (error.Fail())
+ return false;
if (target.GetArchitecture().GetTriple().getOS() ==
llvm::Triple::OSType::Linux) {
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 a3b91fc37dac..f0832dbf0734 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
@@ -179,7 +179,7 @@ ObjectFilePDB::loadPDBFile(std::string PdbPath,
llvm::StringRef Path = Buffer->getBufferIdentifier();
auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
- std::move(Buffer), llvm::support::little);
+ std::move(Buffer), llvm::endianness::little);
auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
if (auto EC = File->parseFileHeaders()) {
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 9560ae108f3e..81ee7e328b6c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -74,47 +74,71 @@ llvm::StringRef OperatingSystemPython::GetPluginDescriptionStatic() {
OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process,
const FileSpec &python_module_path)
: OperatingSystem(process), m_thread_list_valobj_sp(), m_register_info_up(),
- m_interpreter(nullptr), m_python_object_sp() {
+ m_interpreter(nullptr), m_script_object_sp() {
if (!process)
return;
TargetSP target_sp = process->CalculateTarget();
if (!target_sp)
return;
m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
- if (m_interpreter) {
-
- std::string os_plugin_class_name(
- python_module_path.GetFilename().AsCString(""));
- if (!os_plugin_class_name.empty()) {
- 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, 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)
- os_plugin_class_name.erase(py_extension_pos);
- // Add ".OperatingSystemPlugIn" to the module name to get a string like
- // "modulename.OperatingSystemPlugIn"
- os_plugin_class_name += ".OperatingSystemPlugIn";
- StructuredData::ObjectSP object_sp =
- m_interpreter->OSPlugin_CreatePluginObject(
- os_plugin_class_name.c_str(), process->CalculateProcess());
- if (object_sp && object_sp->IsValid())
- m_python_object_sp = object_sp;
- }
- }
+ if (!m_interpreter)
+ return;
+
+ std::string os_plugin_class_name(
+ python_module_path.GetFilename().AsCString(""));
+ if (os_plugin_class_name.empty())
+ return;
+
+ 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, options,
+ error))
+ return;
+
+ // 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)
+ os_plugin_class_name.erase(py_extension_pos);
+ // Add ".OperatingSystemPlugIn" to the module name to get a string like
+ // "modulename.OperatingSystemPlugIn"
+ os_plugin_class_name += ".OperatingSystemPlugIn";
+
+ auto operating_system_interface =
+ m_interpreter->CreateOperatingSystemInterface();
+ if (!operating_system_interface)
+ // FIXME: We should pass an Status& to raise the error to the user.
+ // return llvm::createStringError(
+ // llvm::inconvertibleErrorCode(),
+ // "Failed to create scripted thread interface.");
+ return;
+
+ ExecutionContext exe_ctx(process);
+ auto obj_or_err = operating_system_interface->CreatePluginObject(
+ os_plugin_class_name, exe_ctx, nullptr);
+
+ if (!obj_or_err) {
+ llvm::consumeError(obj_or_err.takeError());
+ return;
}
+
+ StructuredData::GenericSP owned_script_object_sp = *obj_or_err;
+ if (!owned_script_object_sp->IsValid())
+ // return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ // "Created script object is invalid.");
+ return;
+
+ m_script_object_sp = owned_script_object_sp;
+ m_operating_system_interface_sp = operating_system_interface;
}
OperatingSystemPython::~OperatingSystemPython() = default;
DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
if (m_register_info_up == nullptr) {
- if (!m_interpreter || !m_python_object_sp)
+ if (!m_interpreter || !m_operating_system_interface_sp)
return nullptr;
Log *log = GetLog(LLDBLog::OS);
@@ -124,7 +148,7 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
m_process->GetID());
StructuredData::DictionarySP dictionary =
- m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp);
+ m_operating_system_interface_sp->GetRegisterInfo();
if (!dictionary)
return nullptr;
@@ -140,27 +164,11 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
ThreadList &core_thread_list,
ThreadList &new_thread_list) {
- if (!m_interpreter || !m_python_object_sp)
+ if (!m_interpreter || !m_operating_system_interface_sp)
return false;
Log *log = GetLog(LLDBLog::OS);
- // First thing we have to do is to try to get the API lock, and the
- // interpreter lock. We're going to change the thread content of the process,
- // and we're going to use python, which requires the API lock to do it. We
- // need the interpreter lock to make sure thread_info_dict stays alive.
- //
- // If someone already has the API lock, that is ok, we just want to avoid
- // external code from making new API calls while this call is happening.
- //
- // This is a recursive lock so we can grant it to any Python code called on
- // the stack below us.
- Target &target = m_process->GetTarget();
- std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
- std::defer_lock);
- (void)api_lock.try_lock(); // See above.
- auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
-
LLDB_LOGF(log,
"OperatingSystemPython::UpdateThreadList() fetching thread "
"data from python for pid %" PRIu64,
@@ -170,7 +178,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
// the lldb_private::Process subclass, no memory threads will be in this
// list.
StructuredData::ArraySP threads_list =
- m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp);
+ m_operating_system_interface_sp->GetThreadInfo();
const uint32_t num_cores = core_thread_list.GetSize(false);
@@ -281,28 +289,12 @@ RegisterContextSP
OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
addr_t reg_data_addr) {
RegisterContextSP reg_ctx_sp;
- if (!m_interpreter || !m_python_object_sp || !thread)
+ if (!m_interpreter || !m_script_object_sp || !thread)
return reg_ctx_sp;
if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
return reg_ctx_sp;
- // First thing we have to do is to try to get the API lock, and the
- // interpreter lock. We're going to change the thread content of the process,
- // and we're going to use python, which requires the API lock to do it. We
- // need the interpreter lock to make sure thread_info_dict stays alive.
- //
- // If someone already has the API lock, that is ok, we just want to avoid
- // external code from making new API calls while this call is happening.
- //
- // This is a recursive lock so we can grant it to any Python code called on
- // the stack below us.
- Target &target = m_process->GetTarget();
- std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
- std::defer_lock);
- (void)api_lock.try_lock(); // See above.
- auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
-
Log *log = GetLog(LLDBLog::Thread);
if (reg_data_addr != LLDB_INVALID_ADDRESS) {
@@ -324,11 +316,11 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
") fetching register data from python",
thread->GetID(), thread->GetProtocolID());
- StructuredData::StringSP reg_context_data =
- m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp,
- thread->GetID());
+ std::optional<std::string> reg_context_data =
+ m_operating_system_interface_sp->GetRegisterContextForTID(
+ thread->GetID());
if (reg_context_data) {
- std::string value = std::string(reg_context_data->GetValue());
+ std::string value = *reg_context_data;
DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length()));
if (data_sp->GetByteSize()) {
RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory(
@@ -347,6 +339,7 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
"OperatingSystemPython::CreateRegisterContextForThread (tid "
"= 0x%" PRIx64 ") forcing a dummy register context",
thread->GetID());
+ Target &target = m_process->GetTarget();
reg_ctx_sp = std::make_shared<RegisterContextDummy>(
*thread, 0, target.GetArchitecture().GetAddressByteSize());
}
@@ -372,26 +365,11 @@ lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid,
", context = 0x%" PRIx64 ") fetching register data from python",
tid, context);
- if (m_interpreter && m_python_object_sp) {
- // First thing we have to do is to try to get the API lock, and the
- // interpreter lock. We're going to change the thread content of the
- // process, and we're going to use python, which requires the API lock to
- // do it. We need the interpreter lock to make sure thread_info_dict stays
- // alive.
- //
- // If someone already has the API lock, that is ok, we just want to avoid
- // external code from making new API calls while this call is happening.
- //
- // This is a recursive lock so we can grant it to any Python code called on
- // the stack below us.
- Target &target = m_process->GetTarget();
- std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
- std::defer_lock);
- (void)api_lock.try_lock(); // See above.
- auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
+ if (m_interpreter && m_script_object_sp) {
StructuredData::DictionarySP thread_info_dict =
- m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context);
+ m_operating_system_interface_sp->CreateThread(tid, context);
+
std::vector<bool> core_used_map;
if (thread_info_dict) {
ThreadList core_threads(m_process);
diff --git a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
index 7800cf03af8e..90973acde3eb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
+++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
@@ -62,7 +62,7 @@ public:
protected:
bool IsValid() const {
- return m_python_object_sp && m_python_object_sp->IsValid();
+ return m_script_object_sp && m_script_object_sp->IsValid();
}
lldb::ThreadSP CreateThreadFromThreadInfo(
@@ -75,8 +75,9 @@ protected:
lldb::ValueObjectSP m_thread_list_valobj_sp;
std::unique_ptr<lldb_private::DynamicRegisterInfo> m_register_info_up;
- lldb_private::ScriptInterpreter *m_interpreter;
- lldb_private::StructuredData::ObjectSP m_python_object_sp;
+ lldb_private::ScriptInterpreter *m_interpreter = nullptr;
+ lldb::OperatingSystemInterfaceSP m_operating_system_interface_sp = nullptr;
+ lldb_private::StructuredData::GenericSP m_script_object_sp = nullptr;
};
#endif // LLDB_ENABLE_PYTHON
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 7abc71a1c53f..d7584be2b95e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -206,7 +206,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {
CompilerType sigval_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
- clang::TTK_Union, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(sigval_type);
ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
lldb::eAccessPublic, 0);
@@ -217,7 +217,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {
// siginfo_t
CompilerType siginfo_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
- clang::TTK_Struct, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(siginfo_type);
ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type,
lldb::eAccessPublic, 0);
@@ -239,7 +239,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {
// union used to hold the signal data
CompilerType union_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
- clang::TTK_Union, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(union_type);
ast->AddFieldToRecordType(
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 393519d708d3..ce81aab55706 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -228,7 +228,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
CompilerType sigval_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
- clang::TTK_Union, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(sigval_type);
ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
lldb::eAccessPublic, 0);
@@ -238,7 +238,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
CompilerType ptrace_option_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
- clang::TTK_Union, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(ptrace_option_type);
ast->AddFieldToRecordType(ptrace_option_type, "_pe_other_pid", pid_type,
lldb::eAccessPublic, 0);
@@ -249,13 +249,13 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
// siginfo_t
CompilerType siginfo_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
- clang::TTK_Union, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(siginfo_type);
// struct _ksiginfo
CompilerType ksiginfo_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
- clang::TTK_Struct, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(ksiginfo_type);
ast->AddFieldToRecordType(ksiginfo_type, "_signo", int_type,
lldb::eAccessPublic, 0);
@@ -272,7 +272,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
// union used to hold the signal data
CompilerType union_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
- clang::TTK_Union, lldb::eLanguageTypeC);
+ llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(union_type);
ast->AddFieldToRecordType(
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 1e91f2ccd198..b4f1b76c39db 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -949,7 +949,7 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
Status PlatformPOSIX::UnloadImage(lldb_private::Process *process,
uint32_t image_token) {
const addr_t image_addr = process->GetImagePtrFromToken(image_token);
- if (image_addr == LLDB_INVALID_ADDRESS)
+ if (image_addr == LLDB_INVALID_IMAGE_TOKEN)
return Status("Invalid image token");
StreamString expr;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
index 72a039d18872..460f5560573d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
@@ -36,7 +36,7 @@ class PluginProperties : public Properties {
public:
PluginProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(
- ConstString(PlatformQemuUser::GetPluginNameStatic()));
+ PlatformQemuUser::GetPluginNameStatic());
m_collection_sp->Initialize(g_platformqemuuser_properties);
}
@@ -89,8 +89,8 @@ void PlatformQemuUser::Terminate() {
}
void PlatformQemuUser::DebuggerInitialize(Debugger &debugger) {
- if (!PluginManager::GetSettingForPlatformPlugin(
- debugger, ConstString(GetPluginNameStatic()))) {
+ if (!PluginManager::GetSettingForPlatformPlugin(debugger,
+ GetPluginNameStatic())) {
PluginManager::CreateSettingForPlatformPlugin(
debugger, GetGlobalProperties().GetValueProperties(),
"Properties for the qemu-user platform plugin.",
@@ -162,9 +162,18 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
Target &target, Status &error) {
Log *log = GetLog(LLDBLog::Platform);
+ // If platform.plugin.qemu-user.emulator-path is set, use it.
FileSpec qemu = GetGlobalProperties().GetEmulatorPath();
- if (!qemu)
- qemu.SetPath(("qemu-" + GetGlobalProperties().GetArchitecture()).str());
+ // If platform.plugin.qemu-user.emulator-path is not set, build the
+ // executable name from platform.plugin.qemu-user.architecture.
+ if (!qemu) {
+ llvm::StringRef arch = GetGlobalProperties().GetArchitecture();
+ // If platform.plugin.qemu-user.architecture is not set, build the
+ // executable name from the target Triple's ArchName
+ if (arch.empty())
+ arch = target.GetArchitecture().GetTriple().getArchName();
+ qemu.SetPath(("qemu-" + arch).str());
+ }
FileSystem::Instance().ResolveExecutableLocation(qemu);
llvm::SmallString<0> socket_model, socket_path;
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 053d79b8c3b5..88f1ad15b6b4 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
@@ -15,7 +15,6 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
@@ -29,10 +28,12 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/UriParser.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FormatAdapters.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
+#include <mutex>
#include <optional>
using namespace lldb;
@@ -42,6 +43,11 @@ using namespace lldb_private::platform_gdb_server;
LLDB_PLUGIN_DEFINE_ADV(PlatformRemoteGDBServer, PlatformGDB)
static bool g_initialized = false;
+// UnixSignals does not store the signal names or descriptions itself.
+// It holds onto StringRefs. Becaue we may get signal information dynamically
+// from the remote, these strings need persistent storage client-side.
+static std::mutex g_signal_string_mutex;
+static llvm::StringSet<> g_signal_string_storage;
void PlatformRemoteGDBServer::Initialize() {
Platform::Initialize();
@@ -750,8 +756,18 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
if (object_sp && object_sp->IsValid())
description = std::string(object_sp->GetStringValue());
- remote_signals_sp->AddSignal(signo, name.str().c_str(), suppress, stop,
- notify, description.c_str());
+ llvm::StringRef name_backed, description_backed;
+ {
+ std::lock_guard<std::mutex> guard(g_signal_string_mutex);
+ name_backed =
+ g_signal_string_storage.insert(name).first->getKeyData();
+ if (!description.empty())
+ description_backed =
+ g_signal_string_storage.insert(description).first->getKeyData();
+ }
+
+ remote_signals_sp->AddSignal(signo, name_backed, suppress, stop, notify,
+ description_backed);
return true;
});
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 84a009be50bf..19e0986ace31 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -69,7 +69,7 @@ NativeProcessFreeBSD::Manager::Launch(ProcessLaunchInfo &launch_info,
int wstatus;
::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
assert(wpid == pid);
- (void)wpid;
+ UNUSED_IF_ASSERT_DISABLED(wpid);
if (!WIFSTOPPED(wstatus)) {
LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
WaitStatus::Decode(wstatus));
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index 30eace1ba94f..0019b4d65f15 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -10,7 +10,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/DynamicLoader.h"
-#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
+#include "Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h"
#include "ProcessFreeBSDKernel.h"
#include "ThreadFreeBSDKernel.h"
@@ -267,7 +267,7 @@ Status ProcessFreeBSDKernel::DoLoadCore() {
DynamicLoader *ProcessFreeBSDKernel::GetDynamicLoader() {
if (m_dyld_up.get() == nullptr)
m_dyld_up.reset(DynamicLoader::FindPlugin(
- this, DynamicLoaderStatic::GetPluginNameStatic()));
+ this, DynamicLoaderFreeBSDKernel::GetPluginNameStatic()));
return m_dyld_up.get();
}
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 26c562bd4790..451bb4866037 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -379,6 +379,29 @@ void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
SetState(StateType::eStateStopped, true);
}
+Status NativeProcessNetBSD::StopProcess(lldb::pid_t pid) {
+#ifdef PT_STOP
+ return PtraceWrapper(PT_STOP, pid);
+#else
+ Log *log = GetLog(POSIXLog::Ptrace);
+ Status error;
+ int ret;
+
+ errno = 0;
+ ret = kill(pid, SIGSTOP);
+
+ if (ret == -1)
+ error.SetErrorToErrno();
+
+ LLDB_LOG(log, "kill({0}, SIGSTOP)", pid);
+
+ if (error.Fail())
+ LLDB_LOG(log, "kill() failed: {0}", error);
+
+ return error;
+#endif
+}
+
Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
int data, int *result) {
Log *log = GetLog(POSIXLog::Ptrace);
@@ -531,7 +554,7 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
return ret;
}
-Status NativeProcessNetBSD::Halt() { return PtraceWrapper(PT_STOP, GetID()); }
+Status NativeProcessNetBSD::Halt() { return StopProcess(GetID()); }
Status NativeProcessNetBSD::Detach() {
Status error;
@@ -555,9 +578,7 @@ Status NativeProcessNetBSD::Signal(int signo) {
return error;
}
-Status NativeProcessNetBSD::Interrupt() {
- return PtraceWrapper(PT_STOP, GetID());
-}
+Status NativeProcessNetBSD::Interrupt() { return StopProcess(GetID()); }
Status NativeProcessNetBSD::Kill() {
Log *log = GetLog(POSIXLog::Process);
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 86724fdd5b7e..f3d07651384f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -88,6 +88,7 @@ public:
// Interface used by NativeRegisterContext-derived classes.
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
int data = 0, int *result = nullptr);
+ static Status StopProcess(lldb::pid_t pid);
llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 0a1f34ec6b4e..32c71d87c7f5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -9,7 +9,6 @@
#include "InferiorCallPOSIX.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Host/Config.h"
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 817dca336de7..8b5393ca1888 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
@@ -152,6 +152,8 @@ struct user_sve_header {
uint16_t reserved;
};
+using user_za_header = user_sve_header;
+
/* Definitions for user_sve_header.flags: */
const uint16_t ptrace_regs_mask = 1 << 0;
const uint16_t ptrace_regs_fpsimd = 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h
index e6740a304a02..94bad7c19a49 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.h
@@ -1,4 +1,4 @@
-//===-- NetBSDSignals.h ----------------------------------------*- C++ -*-===//
+//===-- NetBSDSignals.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.
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp
index ba089190bd22..a160c87db6cf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp
@@ -1,10 +1,10 @@
-//===-- RegisterContextNetBSD_i386.cpp -------------------------*- C++ -*-===//
+//===-- RegisterContextNetBSD_i386.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 "RegisterContextNetBSD_i386.h"
#include "RegisterContextPOSIX_x86.h"
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
index b7b8d33b7c37..6f9787506013 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextNetBSD_x86_64.h -------------------------*- C++ -*-===//
+//===-- RegisterContextNetBSD_x86_64.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.
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 d306c818e89f..50e25568f2ae 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
@@ -43,6 +43,10 @@ bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const {
return m_register_info_up->IsSVEReg(reg);
}
+bool RegisterContextPOSIX_arm64::IsSME(unsigned reg) const {
+ return m_register_info_up->IsSMEReg(reg);
+}
+
bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const {
return m_register_info_up->IsPAuthReg(reg);
}
@@ -51,6 +55,10 @@ bool RegisterContextPOSIX_arm64::IsTLS(unsigned reg) const {
return m_register_info_up->IsTLSReg(reg);
}
+bool RegisterContextPOSIX_arm64::IsMTE(unsigned reg) const {
+ return m_register_info_up->IsMTEReg(reg);
+}
+
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
lldb_private::Thread &thread,
std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
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 6a935274fc40..b1226b25b4be 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
@@ -56,12 +56,17 @@ protected:
bool IsSVE(unsigned reg) const;
bool IsPAuth(unsigned reg) const;
bool IsTLS(unsigned reg) const;
+ bool IsSME(unsigned reg) const;
+ bool IsMTE(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); }
bool IsSVEVG(unsigned reg) const {
return m_register_info_up->IsSVERegVG(reg);
}
+ bool IsSMEZA(unsigned reg) const {
+ return m_register_info_up->IsSMERegZA(reg);
+ }
uint32_t GetRegNumSVEZ0() const {
return m_register_info_up->GetRegNumSVEZ0();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp
new file mode 100644
index 000000000000..51553817921f
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp
@@ -0,0 +1,202 @@
+//===-- RegisterFlagsLinux_arm64.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 "RegisterFlagsLinux_arm64.h"
+#include "lldb/lldb-private-types.h"
+
+// This file is built on all systems because it is used by native processes and
+// core files, so we manually define the needed HWCAP values here.
+
+#define HWCAP_FPHP (1ULL << 9)
+#define HWCAP_ASIMDHP (1ULL << 10)
+#define HWCAP_DIT (1ULL << 24)
+#define HWCAP_SSBS (1ULL << 28)
+
+#define HWCAP2_BTI (1ULL << 17)
+#define HWCAP2_MTE (1ULL << 18)
+#define HWCAP2_AFP (1ULL << 20)
+#define HWCAP2_EBF16 (1ULL << 32)
+
+using namespace lldb_private;
+
+LinuxArm64RegisterFlags::Fields
+LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
+ (void)hwcap;
+ (void)hwcap2;
+ // Represents the pseudo register that lldb-server builds, which itself
+ // matches the architectural register SCVR. The fields match SVCR in the Arm
+ // manual.
+ return {
+ {"ZA", 1},
+ {"SM", 0},
+ };
+}
+
+LinuxArm64RegisterFlags::Fields
+LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) {
+ (void)hwcap;
+ (void)hwcap2;
+ // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed
+ // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines
+ // used to build the value.
+ return {{"TAGS", 3, 18}, // 16 bit bitfield shifted up by PR_MTE_TAG_SHIFT.
+ {"TCF_ASYNC", 2},
+ {"TCF_SYNC", 1},
+ {"TAGGED_ADDR_ENABLE", 0}};
+}
+
+LinuxArm64RegisterFlags::Fields
+LinuxArm64RegisterFlags::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
+ std::vector<RegisterFlags::Field> fpcr_fields{
+ {"AHP", 26}, {"DN", 25}, {"FZ", 24}, {"RMode", 22, 23},
+ // Bits 21-20 are "Stride" which is unused in AArch64 state.
+ };
+
+ // FEAT_FP16 is indicated by the presence of FPHP (floating point half
+ // precision) and ASIMDHP (Advanced SIMD half precision) features.
+ if ((hwcap & HWCAP_FPHP) && (hwcap & HWCAP_ASIMDHP))
+ fpcr_fields.push_back({"FZ16", 19});
+
+ // Bits 18-16 are "Len" which is unused in AArch64 state.
+
+ fpcr_fields.push_back({"IDE", 15});
+
+ // Bit 14 is unused.
+ if (hwcap2 & HWCAP2_EBF16)
+ fpcr_fields.push_back({"EBF", 13});
+
+ fpcr_fields.push_back({"IXE", 12});
+ fpcr_fields.push_back({"UFE", 11});
+ fpcr_fields.push_back({"OFE", 10});
+ fpcr_fields.push_back({"DZE", 9});
+ fpcr_fields.push_back({"IOE", 8});
+ // Bits 7-3 reserved.
+
+ if (hwcap2 & HWCAP2_AFP) {
+ fpcr_fields.push_back({"NEP", 2});
+ fpcr_fields.push_back({"AH", 1});
+ fpcr_fields.push_back({"FIZ", 0});
+ }
+
+ return fpcr_fields;
+}
+
+LinuxArm64RegisterFlags::Fields
+LinuxArm64RegisterFlags::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) {
+ // fpsr's contents are constant.
+ (void)hwcap;
+ (void)hwcap2;
+
+ return {
+ // Bits 31-28 are N/Z/C/V, only used by AArch32.
+ {"QC", 27},
+ // Bits 26-8 reserved.
+ {"IDC", 7},
+ // Bits 6-5 reserved.
+ {"IXC", 4},
+ {"UFC", 3},
+ {"OFC", 2},
+ {"DZC", 1},
+ {"IOC", 0},
+ };
+}
+
+LinuxArm64RegisterFlags::Fields
+LinuxArm64RegisterFlags::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) {
+ // The fields here are a combination of the Arm manual's SPSR_EL1,
+ // plus a few changes where Linux has decided not to make use of them at all,
+ // or at least not from userspace.
+
+ // Status bits that are always present.
+ std::vector<RegisterFlags::Field> cpsr_fields{
+ {"N", 31}, {"Z", 30}, {"C", 29}, {"V", 28},
+ // Bits 27-26 reserved.
+ };
+
+ if (hwcap2 & HWCAP2_MTE)
+ cpsr_fields.push_back({"TCO", 25});
+ if (hwcap & HWCAP_DIT)
+ cpsr_fields.push_back({"DIT", 24});
+
+ // UAO and PAN are bits 23 and 22 and have no meaning for userspace so
+ // are treated as reserved by the kernel.
+
+ cpsr_fields.push_back({"SS", 21});
+ cpsr_fields.push_back({"IL", 20});
+ // Bits 19-14 reserved.
+
+ // Bit 13, ALLINT, requires FEAT_NMI that isn't relevant to userspace, and we
+ // can't detect either, don't show this field.
+ if (hwcap & HWCAP_SSBS)
+ cpsr_fields.push_back({"SSBS", 12});
+ if (hwcap2 & HWCAP2_BTI)
+ cpsr_fields.push_back({"BTYPE", 10, 11});
+
+ cpsr_fields.push_back({"D", 9});
+ cpsr_fields.push_back({"A", 8});
+ cpsr_fields.push_back({"I", 7});
+ cpsr_fields.push_back({"F", 6});
+ // Bit 5 reserved
+ // Called "M" in the ARMARM.
+ cpsr_fields.push_back({"nRW", 4});
+ // This is a 4 bit field M[3:0] in the ARMARM, we split it into parts.
+ cpsr_fields.push_back({"EL", 2, 3});
+ // Bit 1 is unused and expected to be 0.
+ cpsr_fields.push_back({"SP", 0});
+
+ return cpsr_fields;
+}
+
+void LinuxArm64RegisterFlags::DetectFields(uint64_t hwcap, uint64_t hwcap2) {
+ for (auto &reg : m_registers)
+ reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2));
+ m_has_detected = true;
+}
+
+void LinuxArm64RegisterFlags::UpdateRegisterInfo(const RegisterInfo *reg_info,
+ uint32_t num_regs) {
+ assert(m_has_detected &&
+ "Must call DetectFields before updating register info.");
+
+ // Register names will not be duplicated, so we do not want to compare against
+ // one if it has already been found. Each time we find one, we erase it from
+ // this list.
+ std::vector<std::pair<llvm::StringRef, const RegisterFlags *>>
+ search_registers;
+ for (const auto &reg : m_registers) {
+ // It is possible that a register is all extension dependent fields, and
+ // none of them are present.
+ if (reg.m_flags.GetFields().size())
+ search_registers.push_back({reg.m_name, &reg.m_flags});
+ }
+
+ // Walk register information while there are registers we know need
+ // to be updated. Example:
+ // Register information: [a, b, c, d]
+ // To be patched: [b, c]
+ // * a != b, a != c, do nothing and move on.
+ // * b == b, patch b, new patch list is [c], move on.
+ // * c == c, patch c, patch list is empty, exit early without looking at d.
+ for (uint32_t idx = 0; idx < num_regs && search_registers.size();
+ ++idx, ++reg_info) {
+ auto reg_it = std::find_if(
+ search_registers.cbegin(), search_registers.cend(),
+ [reg_info](auto reg) { return reg.first == reg_info->name; });
+
+ if (reg_it != search_registers.end()) {
+ // Attach the field information.
+ reg_info->flags_type = reg_it->second;
+ // We do not expect to see this name again so don't look for it again.
+ search_registers.erase(reg_it);
+ }
+ }
+
+ // We do not assert that search_registers is empty here, because it may
+ // contain registers from optional extensions that are not present on the
+ // current target.
+} \ No newline at end of file
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h
new file mode 100644
index 000000000000..660bef08700f
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h
@@ -0,0 +1,86 @@
+//===-- RegisterFlagsLinux_arm64.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_REGISTERFLAGSLINUX_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSLINUX_ARM64_H
+
+#include "lldb/Target/RegisterFlags.h"
+#include "llvm/ADT/StringRef.h"
+#include <functional>
+
+namespace lldb_private {
+
+struct RegisterInfo;
+
+/// This class manages the storage and detection of register field information
+/// for Arm64 Linux registers. The same register may have different fields on
+/// different CPUs. This class abstracts out the field detection process so we
+/// can use it on live processes and core files.
+///
+/// The general way to use this class is:
+/// * Make an instance somewhere that will last as long as the debug session
+/// (because your final register info will point to this instance).
+/// * Read hardware capabilities from a core note, binary, prctl, etc.
+/// * Pass those to DetectFields.
+/// * Call UpdateRegisterInfo with your RegisterInfo to add pointers
+/// to the detected fields for all registers listed in this class.
+///
+/// This must be done in that order, and you should ensure that if multiple
+/// threads will reference the information, a mutex is used to make sure only
+/// one calls DetectFields.
+class LinuxArm64RegisterFlags {
+public:
+ /// For the registers listed in this class, detect which fields are
+ /// present. Must be called before UpdateRegisterInfos.
+ /// If called more than once, fields will be redetected each time from
+ /// scratch. If you do not have access to hwcap, just pass 0 for each one, you
+ /// will only get unconditional fields.
+ void DetectFields(uint64_t hwcap, uint64_t hwcap2);
+
+ /// Add the field information of any registers named in this class,
+ /// to the relevant RegisterInfo instances. Note that this will be done
+ /// with a pointer to the instance of this class that you call this on, so
+ /// the lifetime of that instance must be at least that of the register info.
+ void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs);
+
+ /// Returns true if field detection has been run at least once.
+ bool HasDetected() const { return m_has_detected; }
+
+private:
+ using Fields = std::vector<RegisterFlags::Field>;
+ using DetectorFn = std::function<Fields(uint64_t, uint64_t)>;
+
+ static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2);
+
+ struct RegisterEntry {
+ RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
+ : m_name(name), m_flags(std::string(name) + "_flags", size, {{"", 0}}),
+ m_detector(detector) {}
+
+ llvm::StringRef m_name;
+ RegisterFlags m_flags;
+ DetectorFn m_detector;
+ } m_registers[5] = {
+ RegisterEntry("cpsr", 4, DetectCPSRFields),
+ RegisterEntry("fpsr", 4, DetectFPSRFields),
+ RegisterEntry("fpcr", 4, DetectFPCRFields),
+ RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
+ RegisterEntry("svcr", 8, DetectSVCRFields),
+ };
+
+ // Becomes true once field detection has been run for all registers.
+ bool m_has_detected = false;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSLINUX_ARM64_H \ No newline at end of file
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 af5bbda7bfcf..054b7d9b2ec5 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
@@ -79,7 +79,20 @@ static lldb_private::RegisterInfo g_register_infos_mte[] = {
DEFINE_EXTENSION_REG(mte_ctrl)};
static lldb_private::RegisterInfo g_register_infos_tls[] = {
- DEFINE_EXTENSION_REG(tpidr)};
+ DEFINE_EXTENSION_REG(tpidr),
+ // Only present when SME is present
+ DEFINE_EXTENSION_REG(tpidr2)};
+
+static lldb_private::RegisterInfo g_register_infos_sme[] = {
+ DEFINE_EXTENSION_REG(svcr),
+ DEFINE_EXTENSION_REG(svg),
+ // 16 is a default size we will change later.
+ {"za", nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8,
+ KIND_ALL_INVALID, nullptr, nullptr, nullptr}};
+
+static lldb_private::RegisterInfo g_register_infos_sme2[] = {
+ {"zt0", nullptr, 64, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8,
+ KIND_ALL_INVALID, nullptr, nullptr, nullptr}};
// Number of register sets provided by this context.
enum {
@@ -87,8 +100,11 @@ enum {
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_tls_register = 1,
+ // Number of TLS registers is dynamic so it is not listed here.
k_num_pauth_register = 2,
+ // SME2's ZT0 will also be added to this set if present. So this number is
+ // only for SME1 registers.
+ k_num_sme_register = 3,
k_num_register_sets_default = 2,
k_num_register_sets = 3
};
@@ -193,8 +209,10 @@ static const lldb_private::RegisterSet g_reg_set_pauth_arm64 = {
static const lldb_private::RegisterSet g_reg_set_mte_arm64 = {
"MTE Control Register", "mte", k_num_mte_register, nullptr};
-static const lldb_private::RegisterSet g_reg_set_tls_arm64 = {
- "Thread Local Storage Registers", "tls", k_num_tls_register, nullptr};
+// The size of the TLS set is dynamic, so not listed here.
+
+static const lldb_private::RegisterSet g_reg_set_sme_arm64 = {
+ "Scalable Matrix Extension Registers", "sme", k_num_sme_register, nullptr};
RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets)
@@ -212,7 +230,7 @@ RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
// 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)) {
+ if (m_opt_regsets.AnySet(eRegsetMaskSVE | eRegsetMaskSSVE)) {
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++] =
@@ -236,9 +254,12 @@ RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
if (m_opt_regsets.AllSet(eRegsetMaskMTE))
AddRegSetMTE();
- // tpidr is always present, but in future there will be others so this is
- // done as a dynamic set.
- AddRegSetTLS();
+ // The TLS set always contains tpidr but only has tpidr2 when SME is
+ // present.
+ AddRegSetTLS(m_opt_regsets.AllSet(eRegsetMaskSSVE));
+
+ if (m_opt_regsets.AnySet(eRegsetMaskSSVE))
+ AddRegSetSME(m_opt_regsets.AnySet(eRegsetMaskZT));
m_register_info_count = m_dynamic_reg_infos.size();
m_register_info_p = m_dynamic_reg_infos.data();
@@ -323,22 +344,70 @@ void RegisterInfoPOSIX_arm64::AddRegSetMTE() {
m_dynamic_reg_sets.back().registers = m_mte_regnum_collection.data();
}
-void RegisterInfoPOSIX_arm64::AddRegSetTLS() {
+void RegisterInfoPOSIX_arm64::AddRegSetTLS(bool has_tpidr2) {
uint32_t tls_regnum = m_dynamic_reg_infos.size();
- m_tls_regnum_collection.push_back(tls_regnum);
- m_dynamic_reg_infos.push_back(g_register_infos_tls[0]);
- m_dynamic_reg_infos[tls_regnum].byte_offset =
- m_dynamic_reg_infos[tls_regnum - 1].byte_offset +
- m_dynamic_reg_infos[tls_regnum - 1].byte_size;
- m_dynamic_reg_infos[tls_regnum].kinds[lldb::eRegisterKindLLDB] = tls_regnum;
+ uint32_t num_regs = has_tpidr2 ? 2 : 1;
+ for (uint32_t i = 0; i < num_regs; i++) {
+ m_tls_regnum_collection.push_back(tls_regnum + i);
+ m_dynamic_reg_infos.push_back(g_register_infos_tls[i]);
+ m_dynamic_reg_infos[tls_regnum + i].byte_offset =
+ m_dynamic_reg_infos[tls_regnum + i - 1].byte_offset +
+ m_dynamic_reg_infos[tls_regnum + i - 1].byte_size;
+ m_dynamic_reg_infos[tls_regnum + i].kinds[lldb::eRegisterKindLLDB] =
+ tls_regnum + i;
+ }
m_per_regset_regnum_range[m_register_set_count] =
- std::make_pair(tls_regnum, tls_regnum + 1);
- m_dynamic_reg_sets.push_back(g_reg_set_tls_arm64);
+ std::make_pair(tls_regnum, m_dynamic_reg_infos.size());
+ m_dynamic_reg_sets.push_back(
+ {"Thread Local Storage Registers", "tls", num_regs, nullptr});
m_dynamic_reg_sets.back().registers = m_tls_regnum_collection.data();
}
-uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) {
+void RegisterInfoPOSIX_arm64::AddRegSetSME(bool has_zt) {
+ const uint32_t first_sme_regnum = m_dynamic_reg_infos.size();
+ uint32_t sme_regnum = first_sme_regnum;
+
+ for (uint32_t i = 0; i < k_num_sme_register; ++i, ++sme_regnum) {
+ m_sme_regnum_collection.push_back(sme_regnum);
+ m_dynamic_reg_infos.push_back(g_register_infos_sme[i]);
+ m_dynamic_reg_infos[sme_regnum].byte_offset =
+ m_dynamic_reg_infos[sme_regnum - 1].byte_offset +
+ m_dynamic_reg_infos[sme_regnum - 1].byte_size;
+ m_dynamic_reg_infos[sme_regnum].kinds[lldb::eRegisterKindLLDB] = sme_regnum;
+ }
+
+ lldb_private::RegisterSet sme_regset = g_reg_set_sme_arm64;
+
+ if (has_zt) {
+ m_sme_regnum_collection.push_back(sme_regnum);
+ m_dynamic_reg_infos.push_back(g_register_infos_sme2[0]);
+ m_dynamic_reg_infos[sme_regnum].byte_offset =
+ m_dynamic_reg_infos[sme_regnum - 1].byte_offset +
+ m_dynamic_reg_infos[sme_regnum - 1].byte_size;
+ m_dynamic_reg_infos[sme_regnum].kinds[lldb::eRegisterKindLLDB] = sme_regnum;
+
+ sme_regset.num_registers += 1;
+ }
+
+ m_per_regset_regnum_range[m_register_set_count] =
+ std::make_pair(first_sme_regnum, m_dynamic_reg_infos.size());
+ m_dynamic_reg_sets.push_back(sme_regset);
+ m_dynamic_reg_sets.back().registers = m_sme_regnum_collection.data();
+
+ // When vg is written during streaming mode, svg will also change, as vg and
+ // svg in this state are both showing the streaming vector length.
+ // We model this as vg invalidating svg. In non-streaming mode this doesn't
+ // happen but to keep things simple we will invalidate svg anyway.
+ //
+ // This must be added now, rather than when vg is defined because SME is a
+ // dynamic set that may or may not be present.
+ static uint32_t vg_invalidates[] = {sme_regnum + 1 /*svg*/,
+ LLDB_INVALID_REGNUM};
+ m_dynamic_reg_infos[GetRegNumSVEVG()].invalidate_regs = vg_invalidates;
+}
+
+uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLengthSVE(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
@@ -402,6 +471,20 @@ uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) {
return m_vector_reg_vq;
}
+void RegisterInfoPOSIX_arm64::ConfigureVectorLengthZA(uint32_t za_vq) {
+ if (!VectorSizeIsValid(za_vq) || m_za_reg_vq == za_vq)
+ return;
+
+ m_za_reg_vq = za_vq;
+
+ // For SVE changes, we replace m_register_info_p completely. ZA is in a
+ // dynamic set and is just 1 register so we make an exception to const here.
+ lldb_private::RegisterInfo *non_const_reginfo =
+ const_cast<lldb_private::RegisterInfo *>(m_register_info_p);
+ non_const_reginfo[m_sme_regnum_collection[2]].byte_size =
+ (za_vq * 16) * (za_vq * 16);
+}
+
bool RegisterInfoPOSIX_arm64::IsSVEReg(unsigned reg) const {
if (m_vector_reg_vq > eVectorQuadwordAArch64)
return (sve_vg <= reg && reg <= sve_ffr);
@@ -421,6 +504,16 @@ bool RegisterInfoPOSIX_arm64::IsSVERegVG(unsigned reg) const {
return sve_vg == reg;
}
+bool RegisterInfoPOSIX_arm64::IsSMERegZA(unsigned reg) const {
+ return reg == m_sme_regnum_collection[2];
+}
+
+bool RegisterInfoPOSIX_arm64::IsSMERegZT(unsigned reg) const {
+ // ZT0 is part of the SME register set only if SME2 is present.
+ return m_sme_regnum_collection.size() >= 4 &&
+ reg == m_sme_regnum_collection[3];
+}
+
bool RegisterInfoPOSIX_arm64::IsPAuthReg(unsigned reg) const {
return llvm::is_contained(pauth_regnum_collection, reg);
}
@@ -433,6 +526,10 @@ bool RegisterInfoPOSIX_arm64::IsTLSReg(unsigned reg) const {
return llvm::is_contained(m_tls_regnum_collection, reg);
}
+bool RegisterInfoPOSIX_arm64::IsSMEReg(unsigned reg) const {
+ return llvm::is_contained(m_sme_regnum_collection, reg);
+}
+
uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; }
uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; }
@@ -443,6 +540,10 @@ uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPSR() const { return fpu_fpsr; }
uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; }
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSMESVG() const {
+ return m_sme_regnum_collection[1];
+}
+
uint32_t RegisterInfoPOSIX_arm64::GetPAuthOffset() const {
return m_register_info_p[pauth_regnum_collection[0]].byte_offset;
}
@@ -454,3 +555,7 @@ uint32_t RegisterInfoPOSIX_arm64::GetMTEOffset() const {
uint32_t RegisterInfoPOSIX_arm64::GetTLSOffset() const {
return m_register_info_p[m_tls_regnum_collection[0]].byte_offset;
}
+
+uint32_t RegisterInfoPOSIX_arm64::GetSMEOffset() const {
+ return m_register_info_p[m_sme_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 20cfe732c6c2..3b8171042c73 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
@@ -15,7 +15,7 @@
#include "lldb/lldb-private.h"
#include <map>
-enum class SVEState { Unknown, Disabled, FPSIMD, Full };
+enum class SVEState : uint8_t { Unknown, Disabled, FPSIMD, Full, Streaming };
class RegisterInfoPOSIX_arm64
: public lldb_private::RegisterInfoAndSetInterface {
@@ -26,9 +26,12 @@ public:
enum {
eRegsetMaskDefault = 0,
eRegsetMaskSVE = 1,
- eRegsetMaskPAuth = 2,
- eRegsetMaskMTE = 4,
- eRegsetMaskTLS = 8,
+ eRegsetMaskSSVE = 2,
+ eRegsetMaskPAuth = 4,
+ eRegsetMaskMTE = 8,
+ eRegsetMaskTLS = 16,
+ eRegsetMaskZA = 32,
+ eRegsetMaskZT = 64,
eRegsetMaskDynamic = ~1,
};
@@ -103,9 +106,13 @@ public:
void AddRegSetMTE();
- void AddRegSetTLS();
+ void AddRegSetTLS(bool has_tpidr2);
- uint32_t ConfigureVectorLength(uint32_t sve_vq);
+ void AddRegSetSME(bool has_zt);
+
+ uint32_t ConfigureVectorLengthSVE(uint32_t sve_vq);
+
+ void ConfigureVectorLengthZA(uint32_t za_vq);
bool VectorSizeIsValid(uint32_t vq) {
// coverity[unsigned_compare]
@@ -114,10 +121,13 @@ public:
return false;
}
- bool IsSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
- bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
- bool IsMTEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskMTE); }
- bool IsTLSEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskTLS); }
+ bool IsSVEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
+ bool IsSSVEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskSSVE); }
+ bool IsZAPresent() const { return m_opt_regsets.AnySet(eRegsetMaskZA); }
+ bool IsZTPresent() const { return m_opt_regsets.AnySet(eRegsetMaskZT); }
+ bool IsPAuthPresent() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
+ bool IsMTEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskMTE); }
+ bool IsTLSPresent() const { return m_opt_regsets.AnySet(eRegsetMaskTLS); }
bool IsSVEReg(unsigned reg) const;
bool IsSVEZReg(unsigned reg) const;
@@ -126,15 +136,20 @@ public:
bool IsPAuthReg(unsigned reg) const;
bool IsMTEReg(unsigned reg) const;
bool IsTLSReg(unsigned reg) const;
+ bool IsSMEReg(unsigned reg) const;
+ bool IsSMERegZA(unsigned reg) const;
+ bool IsSMERegZT(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 GetRegNumSMESVG() const;
uint32_t GetPAuthOffset() const;
uint32_t GetMTEOffset() const;
uint32_t GetTLSOffset() const;
+ uint32_t GetSMEOffset() const;
private:
typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>>
@@ -143,7 +158,10 @@ private:
per_vq_register_infos m_per_vq_reg_infos;
uint32_t m_vector_reg_vq = eVectorQuadwordAArch64;
+ uint32_t m_za_reg_vq = eVectorQuadwordAArch64;
+ // In normal operation this is const. Only when SVE or SME registers change
+ // size is it either replaced or the content modified.
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
@@ -162,6 +180,7 @@ private:
std::vector<uint32_t> pauth_regnum_collection;
std::vector<uint32_t> m_mte_regnum_collection;
std::vector<uint32_t> m_tls_regnum_collection;
+ std::vector<uint32_t> m_sme_regnum_collection;
};
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h
index 39428bdd0a08..b111d8f62d1f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h
@@ -71,15 +71,6 @@
nullptr, nullptr, \
}
-// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR_WITH_BASE(reg, alt, kind1, kind2, kind3, kind4) \
- { \
- #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, \
- {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##reg}, nullptr, \
- nullptr, nullptr, \
- }
-
#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
{ \
#name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
@@ -224,8 +215,8 @@ static RegisterInfo g_register_infos_x86_64_with_base[] = {
DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(fs_base, nullptr, dwarf_fs_base_x86_64, dwarf_fs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gs_base, nullptr, dwarf_gs_base_x86_64, dwarf_gs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs_base,nullptr, dwarf_fs_base_x86_64, dwarf_fs_base_x86_64, LLDB_REGNUM_GENERIC_TP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs_base,nullptr, dwarf_gs_base_x86_64, dwarf_gs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
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 d60e6250c7c0..565941d3168f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -491,14 +491,13 @@ static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
uint64_t exc_sub_sub_code) {
// Try hardware watchpoint.
if (target) {
+ // LWP_TODO: We need to find the WatchpointResource that matches
+ // the address, and evaluate its Watchpoints.
+
// The exc_sub_code indicates the data break address.
lldb::WatchpointSP wp_sp =
target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
if (wp_sp && wp_sp->IsEnabled()) {
- // Debugserver may piggyback the hardware index of the fired watchpoint
- // in the exception data. Set the hardware index if that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
}
}
@@ -511,10 +510,6 @@ static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
process_sp->GetBreakpointSiteList().FindByAddress(
(lldb::addr_t)exc_sub_code);
if (bp_sp && bp_sp->IsEnabled()) {
- // Debugserver may piggyback the hardware index of the fired breakpoint
- // in the exception data. Set the hardware index if that's the case.
- if (exc_data_count >= 3)
- bp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithBreakpointSiteID(thread,
bp_sp->GetID());
}
@@ -674,6 +669,9 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
case llvm::Triple::thumb:
if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
+ // LWP_TODO: We need to find the WatchpointResource that matches
+ // the address, and evaluate its Watchpoints.
+
// It's a watchpoint, then, if the exc_sub_code indicates a
// known/enabled data break address from our watchpoint list.
lldb::WatchpointSP wp_sp;
@@ -681,11 +679,6 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
wp_sp = target->GetWatchpointList().FindByAddress(
(lldb::addr_t)exc_sub_code);
if (wp_sp && wp_sp->IsEnabled()) {
- // Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data. Set the hardware index if
- // that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread,
wp_sp->GetID());
} else {
@@ -755,6 +748,9 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
}
if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
+ // LWP_TODO: We need to find the WatchpointResource that matches
+ // the address, and evaluate its Watchpoints.
+
// It's a watchpoint, then, if the exc_sub_code indicates a
// known/enabled data break address from our watchpoint list.
lldb::WatchpointSP wp_sp;
@@ -762,11 +758,6 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
wp_sp = target->GetWatchpointList().FindByAddress(
(lldb::addr_t)exc_sub_code);
if (wp_sp && wp_sp->IsEnabled()) {
- // Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data. Set the hardware index if
- // that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread,
wp_sp->GetID());
}
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 bfb59eceb2d0..7723009787f7 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
@@ -53,7 +53,7 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
bool can_connect) {
lldb::ProcessSP process_sp;
if (crash_file && !can_connect) {
- // Read enough data for a ELF32 header or ELF64 header Note: Here we care
+ // Read enough data for an ELF32 header or ELF64 header Note: Here we care
// about e_type field only, so it is safe to ignore possible presence of
// the header extension.
const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
@@ -108,7 +108,7 @@ ProcessElfCore::~ProcessElfCore() {
// 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();
+ Finalize(true /* destructing */);
}
lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
@@ -131,7 +131,7 @@ lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
m_core_aranges.Append(range_entry);
}
}
- // Keep a separate map of permissions that that isn't coalesced so all ranges
+ // Keep a separate map of permissions that isn't coalesced so all ranges
// are maintained.
const uint32_t permissions =
((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
@@ -832,7 +832,7 @@ llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) {
for (const auto &note : notes) {
// OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so
// match on the initial part of the string.
- if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD"))
+ if (!llvm::StringRef(note.info.n_name).starts_with("OpenBSD"))
continue;
switch (note.info.n_type) {
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 38abd8f8f2b1..07501c10ec3c 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
@@ -9,6 +9,9 @@
#include "RegisterContextPOSIXCore_arm64.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/AuxVector.h"
+#include "Plugins/Process/Utility/RegisterFlagsLinux_arm64.h"
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/RegisterValue.h"
@@ -23,8 +26,13 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
llvm::ArrayRef<CoreNote> notes) {
Flags opt_regsets = RegisterInfoPOSIX_arm64::eRegsetMaskDefault;
+ DataExtractor ssve_data =
+ getRegset(notes, arch.GetTriple(), AARCH64_SSVE_Desc);
+ if (ssve_data.GetByteSize() >= sizeof(sve::user_sve_header))
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSSVE);
+
DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
- if (sve_data.GetByteSize() > sizeof(sve::user_sve_header))
+ if (sve_data.GetByteSize() >= sizeof(sve::user_sve_header))
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
// Pointer Authentication register set data is based on struct
@@ -40,6 +48,22 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
if (tls_data.GetByteSize() >= sizeof(uint64_t))
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
+ DataExtractor za_data = getRegset(notes, arch.GetTriple(), AARCH64_ZA_Desc);
+ // Nothing if ZA is not present, just the header if it is disabled.
+ if (za_data.GetByteSize() >= sizeof(sve::user_za_header))
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskZA);
+
+ DataExtractor mte_data = getRegset(notes, arch.GetTriple(), AARCH64_MTE_Desc);
+ if (mte_data.GetByteSize() >= sizeof(uint64_t))
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskMTE);
+
+ DataExtractor zt_data = getRegset(notes, arch.GetTriple(), AARCH64_ZT_Desc);
+ // Although ZT0 can be in a disabled state like ZA can, the kernel reports
+ // its content as 0s in that state. Therefore even a disabled ZT0 will have
+ // a note containing those 0s. ZT0 is a 512 bit / 64 byte register.
+ if (zt_data.GetByteSize() >= 64)
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskZT);
+
auto register_info_up =
std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
@@ -51,6 +75,23 @@ 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)) {
+ ::memset(&m_sme_pseudo_regs, 0, sizeof(m_sme_pseudo_regs));
+
+ ProcessElfCore *process =
+ static_cast<ProcessElfCore *>(thread.GetProcess().get());
+ if (process->GetArchitecture().GetTriple().getOS() == llvm::Triple::Linux) {
+ AuxVector aux_vec(process->GetAuxvData());
+ std::optional<uint64_t> auxv_at_hwcap =
+ aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP);
+ std::optional<uint64_t> auxv_at_hwcap2 =
+ aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP2);
+
+ m_linux_register_flags.DetectFields(auxv_at_hwcap.value_or(0),
+ auxv_at_hwcap2.value_or(0));
+ m_linux_register_flags.UpdateRegisterInfo(GetRegisterInfo(),
+ GetRegisterCount());
+ }
+
m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
gpregset.GetByteSize()));
m_gpr_data.SetByteOrder(gpregset.GetByteOrder());
@@ -59,15 +100,32 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
m_register_info_up->GetTargetArchitecture().GetTriple();
m_fpr_data = getRegset(notes, target_triple, FPR_Desc);
- if (m_register_info_up->IsSVEEnabled())
+ if (m_register_info_up->IsSSVEPresent()) {
+ m_sve_data = getRegset(notes, target_triple, AARCH64_SSVE_Desc);
+ lldb::offset_t flags_offset = 12;
+ uint16_t flags = m_sve_data.GetU32(&flags_offset);
+ if ((flags & sve::ptrace_regs_mask) == sve::ptrace_regs_sve)
+ m_sve_state = SVEState::Streaming;
+ }
+
+ if (m_sve_state != SVEState::Streaming && m_register_info_up->IsSVEPresent())
m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc);
- if (m_register_info_up->IsPAuthEnabled())
+ if (m_register_info_up->IsPAuthPresent())
m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
- if (m_register_info_up->IsTLSEnabled())
+ if (m_register_info_up->IsTLSPresent())
m_tls_data = getRegset(notes, target_triple, AARCH64_TLS_Desc);
+ if (m_register_info_up->IsZAPresent())
+ m_za_data = getRegset(notes, target_triple, AARCH64_ZA_Desc);
+
+ if (m_register_info_up->IsMTEPresent())
+ m_mte_data = getRegset(notes, target_triple, AARCH64_MTE_Desc);
+
+ if (m_register_info_up->IsZTPresent())
+ m_zt_data = getRegset(notes, target_triple, AARCH64_ZT_Desc);
+
ConfigureRegisterContext();
}
@@ -95,15 +153,18 @@ void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
if (m_sve_data.GetByteSize() > sizeof(sve::user_sve_header)) {
uint64_t sve_header_field_offset = 8;
m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset);
- sve_header_field_offset = 12;
- uint16_t sve_header_flags_field =
- 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;
- else if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
- sve::ptrace_regs_sve)
- m_sve_state = SVEState::Full;
+
+ if (m_sve_state != SVEState::Streaming) {
+ sve_header_field_offset = 12;
+ uint16_t sve_header_flags_field =
+ 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;
+ else if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
+ sve::ptrace_regs_sve)
+ m_sve_state = SVEState::Full;
+ }
if (!sve::vl_valid(m_sve_vector_length)) {
m_sve_state = SVEState::Disabled;
@@ -113,8 +174,25 @@ void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
m_sve_state = SVEState::Disabled;
if (m_sve_state != SVEState::Disabled)
- m_register_info_up->ConfigureVectorLength(
+ m_register_info_up->ConfigureVectorLengthSVE(
sve::vq_from_vl(m_sve_vector_length));
+
+ if (m_sve_state == SVEState::Streaming)
+ m_sme_pseudo_regs.ctrl_reg |= 1;
+
+ if (m_za_data.GetByteSize() >= sizeof(sve::user_za_header)) {
+ lldb::offset_t vlen_offset = 8;
+ uint16_t svl = m_za_data.GetU16(&vlen_offset);
+ m_sme_pseudo_regs.svg_reg = svl / 8;
+ m_register_info_up->ConfigureVectorLengthZA(svl / 16);
+
+ // If there is register data then ZA is active. The size of the note may be
+ // misleading here so we use the size field of the embedded header.
+ lldb::offset_t size_offset = 0;
+ uint32_t size = m_za_data.GetU32(&size_offset);
+ if (size > sizeof(sve::user_za_header))
+ m_sme_pseudo_regs.ctrl_reg |= 1 << 1;
+ }
}
uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset(
@@ -124,7 +202,8 @@ uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset(
if (m_sve_state == SVEState::FPSIMD) {
const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
sve_reg_offset = sve::ptrace_fpsimd_offset + (reg - GetRegNumSVEZ0()) * 16;
- } else if (m_sve_state == SVEState::Full) {
+ } else if (m_sve_state == SVEState::Full ||
+ m_sve_state == SVEState::Streaming) {
uint32_t sve_z0_offset = GetGPRSize() + 16;
sve_reg_offset =
sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset;
@@ -140,11 +219,9 @@ 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_data.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size) {
- value = v;
- return true;
- }
+ value.SetFromMemoryData(*reg_info, m_gpr_data.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
+ return error.Success();
}
const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
@@ -163,19 +240,19 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
}
} else {
// FPSR and FPCR will be located right after Z registers in
- // SVEState::FPSIMD while in SVEState::Full they will be located at the
- // end of register data after an alignment correction based on currently
- // selected vector length.
+ // SVEState::FPSIMD while in SVEState::Full/SVEState::Streaming they will
+ // be located at the end of register data after an alignment correction
+ // based on currently selected vector length.
uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
if (reg == GetRegNumFPSR()) {
sve_reg_num = reg;
- if (m_sve_state == SVEState::Full)
+ if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_vector_length));
else if (m_sve_state == SVEState::FPSIMD)
offset = sve::ptrace_fpsimd_offset + (32 * 16);
} else if (reg == GetRegNumFPCR()) {
sve_reg_num = reg;
- if (m_sve_state == SVEState::Full)
+ if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_vector_length));
else if (m_sve_state == SVEState::FPSIMD)
offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
@@ -217,6 +294,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
error);
} break;
case SVEState::Full:
+ case SVEState::Streaming:
offset = CalculateSVEOffset(reg_info);
assert(offset < m_sve_data.GetByteSize());
value.SetFromMemoryData(*reg_info, GetSVEBuffer(offset),
@@ -237,6 +315,59 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
assert(offset < m_tls_data.GetByteSize());
value.SetFromMemoryData(*reg_info, m_tls_data.GetDataStart() + offset,
reg_info->byte_size, lldb::eByteOrderLittle, error);
+ } else if (IsMTE(reg)) {
+ offset = reg_info->byte_offset - m_register_info_up->GetMTEOffset();
+ assert(offset < m_mte_data.GetByteSize());
+ value.SetFromMemoryData(*reg_info, m_mte_data.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
+ } else if (IsSME(reg)) {
+ // If you had SME in the process, active or otherwise, there will at least
+ // be a ZA header. No header, no SME at all.
+ if (m_za_data.GetByteSize() < sizeof(sve::user_za_header))
+ return false;
+
+ if (m_register_info_up->IsSMERegZA(reg)) {
+ // Don't use the size of the note to tell whether ZA is enabled. There may
+ // be non-register padding data after the header. Use the embedded
+ // header's size field instead.
+ lldb::offset_t size_offset = 0;
+ uint32_t size = m_za_data.GetU32(&size_offset);
+ bool za_enabled = size > sizeof(sve::user_za_header);
+
+ size_t za_note_size = m_za_data.GetByteSize();
+ // For a disabled ZA we fake a value of all 0s.
+ if (!za_enabled) {
+ uint64_t svl = m_sme_pseudo_regs.svg_reg * 8;
+ za_note_size = sizeof(sve::user_za_header) + (svl * svl);
+ }
+
+ const uint8_t *src = nullptr;
+ std::vector<uint8_t> disabled_za_data;
+
+ if (za_enabled)
+ src = m_za_data.GetDataStart();
+ else {
+ disabled_za_data.resize(za_note_size);
+ std::fill(disabled_za_data.begin(), disabled_za_data.end(), 0);
+ src = disabled_za_data.data();
+ }
+
+ value.SetFromMemoryData(*reg_info, src + sizeof(sve::user_za_header),
+ reg_info->byte_size, lldb::eByteOrderLittle,
+ error);
+ } else if (m_register_info_up->IsSMERegZT(reg)) {
+ value.SetFromMemoryData(*reg_info, m_zt_data.GetDataStart(),
+ reg_info->byte_size, lldb::eByteOrderLittle,
+ error);
+ } else {
+ offset = reg_info->byte_offset - m_register_info_up->GetSMEOffset();
+ assert(offset < sizeof(m_sme_pseudo_regs));
+ // Host endian since these values are derived instead of being read from a
+ // core file note.
+ value.SetFromMemoryData(
+ *reg_info, reinterpret_cast<uint8_t *>(&m_sme_pseudo_regs) + offset,
+ reg_info->byte_size, lldb_private::endian::InlHostByteOrder(), 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 5e0e29f0de7f..38e958851dfe 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
@@ -11,6 +11,7 @@
#include "Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "Plugins/Process/Utility/RegisterFlagsLinux_arm64.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -58,10 +59,24 @@ private:
lldb_private::DataExtractor m_sve_data;
lldb_private::DataExtractor m_pac_data;
lldb_private::DataExtractor m_tls_data;
+ lldb_private::DataExtractor m_za_data;
+ lldb_private::DataExtractor m_mte_data;
+ lldb_private::DataExtractor m_zt_data;
- SVEState m_sve_state;
+ SVEState m_sve_state = SVEState::Unknown;
uint16_t m_sve_vector_length = 0;
+ // These are pseudo registers derived from the values in SSVE and ZA data.
+ struct __attribute__((packed)) sme_pseudo_regs {
+ uint64_t ctrl_reg;
+ uint64_t svg_reg;
+ };
+ static_assert(sizeof(sme_pseudo_regs) == 16);
+
+ struct sme_pseudo_regs m_sme_pseudo_regs;
+
+ lldb_private::LinuxArm64RegisterFlags m_linux_register_flags;
+
const uint8_t *GetSVEBuffer(uint64_t offset = 0);
void ConfigureRegisterContext();
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 3d53a5795ef3..12aa5f72371c 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
@@ -119,6 +119,18 @@ constexpr RegsetDesc AARCH64_SVE_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE},
};
+constexpr RegsetDesc AARCH64_SSVE_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SSVE},
+};
+
+constexpr RegsetDesc AARCH64_ZA_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_ZA},
+};
+
+constexpr RegsetDesc AARCH64_ZT_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_ZT},
+};
+
constexpr RegsetDesc AARCH64_PAC_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
};
@@ -127,6 +139,11 @@ constexpr RegsetDesc AARCH64_TLS_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_TLS},
};
+constexpr RegsetDesc AARCH64_MTE_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64,
+ llvm::ELF::NT_ARM_TAGGED_ADDR_CTRL},
+};
+
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/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 7daf003fec7b..8a47eed3d7cb 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
@@ -13,7 +13,6 @@
#include <future>
#include <sys/stat.h>
-#include "lldb/Core/StreamFile.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.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 c6503129685a..ad72b3d121e6 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
@@ -1265,7 +1265,14 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
if (!value.getAsInteger(0, pointer_byte_size))
++num_keys_decoded;
} else if (name.equals("addressing_bits")) {
- if (!value.getAsInteger(0, m_addressing_bits))
+ if (!value.getAsInteger(0, m_low_mem_addressing_bits)) {
+ ++num_keys_decoded;
+ }
+ } else if (name.equals("high_mem_addressing_bits")) {
+ if (!value.getAsInteger(0, m_high_mem_addressing_bits))
+ ++num_keys_decoded;
+ } else if (name.equals("low_mem_addressing_bits")) {
+ if (!value.getAsInteger(0, m_low_mem_addressing_bits))
++num_keys_decoded;
} else if (name.equals("os_version") ||
name.equals("version")) // Older debugserver binaries used
@@ -1407,11 +1414,19 @@ GDBRemoteCommunicationClient::GetHostArchitecture() {
return m_host_arch;
}
-uint32_t GDBRemoteCommunicationClient::GetAddressingBits() {
+AddressableBits GDBRemoteCommunicationClient::GetAddressableBits() {
+ AddressableBits addressable_bits;
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
GetHostInfo();
- return m_addressing_bits;
+
+ if (m_low_mem_addressing_bits == m_high_mem_addressing_bits)
+ addressable_bits.SetAddressableBits(m_low_mem_addressing_bits);
+ else
+ addressable_bits.SetAddressableBits(m_low_mem_addressing_bits,
+ m_high_mem_addressing_bits);
+ return addressable_bits;
}
+
seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
GetHostInfo();
@@ -2634,10 +2649,12 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer(
return 0;
for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
- StructuredData::Dictionary *element = nullptr;
- if (!array->GetItemAtIndexAsDictionary(i, element))
+ std::optional<StructuredData::Dictionary *> maybe_element =
+ array->GetItemAtIndexAsDictionary(i);
+ if (!maybe_element)
continue;
+ StructuredData::Dictionary *element = *maybe_element;
uint16_t port = 0;
if (StructuredData::ObjectSP port_osp =
element->GetValueForKey(llvm::StringRef("port")))
@@ -4025,7 +4042,7 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
return;
} else {
llvm::StringRef response_str(response.GetStringRef());
- if (response_str.startswith("qSymbol:")) {
+ if (response_str.starts_with("qSymbol:")) {
response.SetFilePos(strlen("qSymbol:"));
std::string symbol_name;
if (response.GetHexByteString(symbol_name)) {
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 6cf5de68911b..866b0773d86d 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
@@ -19,6 +19,7 @@
#include <vector>
#include "lldb/Host/File.h"
+#include "lldb/Utility/AddressableBits.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/ProcessInfo.h"
@@ -237,7 +238,7 @@ public:
ArchSpec GetSystemArchitecture();
- uint32_t GetAddressingBits();
+ lldb_private::AddressableBits GetAddressableBits();
bool GetHostname(std::string &s);
@@ -580,7 +581,8 @@ protected:
lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID;
uint32_t m_num_supported_hardware_watchpoints = 0;
- uint32_t m_addressing_bits = 0;
+ uint32_t m_low_mem_addressing_bits = 0;
+ uint32_t m_high_mem_addressing_bits = 0;
ArchSpec m_host_arch;
std::string m_host_distribution_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 a3477caea7d8..5d4a537befeb 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
@@ -9,7 +9,6 @@
#include "GDBRemoteCommunicationHistory.h"
// Other libraries and framework includes
-#include "lldb/Core/StreamFile.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
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 4efc454967a1..3d37bb226a65 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
@@ -595,6 +595,8 @@ static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo &reg_info) {
return "arg7";
case LLDB_REGNUM_GENERIC_ARG8:
return "arg8";
+ case LLDB_REGNUM_GENERIC_TP:
+ return "tp";
default:
return "";
}
@@ -631,7 +633,7 @@ static void WriteRegisterValueInHexFixedWidth(
} else {
// Zero-out any unreadable values.
if (reg_info.byte_size > 0) {
- std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
+ std::vector<uint8_t> zeros(reg_info.byte_size, '\0');
AppendHexValue(response, zeros.data(), zeros.size(), false);
}
}
@@ -2304,7 +2306,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Build the reginfos response.
StreamGDBRemote response;
- RegisterValue reg_value(ArrayRef(m_reg_bytes, reg_size),
+ RegisterValue reg_value(ArrayRef<uint8_t>(m_reg_bytes, reg_size),
m_current_process->GetArchitecture().GetByteOrder());
Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
@@ -3092,6 +3094,12 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
continue;
}
+ if (reg_info->flags_type) {
+ response.IndentMore();
+ reg_info->flags_type->ToXML(response);
+ response.IndentLess();
+ }
+
response.Indent();
response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32
"\" regnum=\"%d\" ",
@@ -3111,6 +3119,9 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
if (!format.empty())
response << "format=\"" << format << "\" ";
+ if (reg_info->flags_type)
+ response << "type=\"" << reg_info->flags_type->GetID() << "\" ";
+
const char *const register_set_name =
reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
if (register_set_name)
@@ -3910,7 +3921,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qSaveCore(
std::string path_hint;
StringRef packet_str{packet.GetStringRef()};
- assert(packet_str.startswith("qSaveCore"));
+ assert(packet_str.starts_with("qSaveCore"));
if (packet_str.consume_front("qSaveCore;")) {
for (auto x : llvm::split(packet_str, ';')) {
if (x.consume_front("path-hint:"))
@@ -3936,7 +3947,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QNonStop(
Log *log = GetLog(LLDBLog::Process);
StringRef packet_str{packet.GetStringRef()};
- assert(packet_str.startswith("QNonStop:"));
+ assert(packet_str.starts_with("QNonStop:"));
packet_str.consume_front("QNonStop:");
if (packet_str == "0") {
if (m_non_stop)
@@ -4295,7 +4306,7 @@ lldb_private::process_gdb_remote::LLGSArgToURL(llvm::StringRef url_arg,
std::string host_port = url_arg.str();
// If host_and_port starts with ':', default the host to be "localhost" and
// expect the remainder to be the port.
- if (url_arg.startswith(":"))
+ if (url_arg.starts_with(":"))
host_port.insert(0, "localhost");
// Try parsing the (preprocessed) argument as host:port pair.
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 4ffa7faa4942..391abdae2752 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
@@ -500,7 +500,7 @@ GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
auto dictionary = std::make_shared<StructuredData::Dictionary>();
dictionary->AddIntegerItem("signo", signo);
- dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
+ dictionary->AddStringItem("name", signals->GetSignalAsStringRef(signo));
bool suppress, stop, notify;
signals->GetSignalInfo(signo, suppress, stop, notify);
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 e8606ddae567..e9bd65fad150 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
@@ -8,6 +8,12 @@
#include "GDBRemoteRegisterContext.h"
+#include "ProcessGDBRemote.h"
+#include "ProcessGDBRemoteLog.h"
+#include "ThreadGDBRemote.h"
+#include "Utility/ARM_DWARF_Registers.h"
+#include "Utility/ARM_ehframe_Registers.h"
+#include "lldb/Core/Architecture.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -15,11 +21,6 @@
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
-#include "ProcessGDBRemote.h"
-#include "ProcessGDBRemoteLog.h"
-#include "ThreadGDBRemote.h"
-#include "Utility/ARM_DWARF_Registers.h"
-#include "Utility/ARM_ehframe_Registers.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
#include <memory>
@@ -227,7 +228,9 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info) {
SetAllRegisterValid(true);
return true;
} else if (buffer_sp->GetByteSize() > 0) {
- for (auto x : llvm::enumerate(m_reg_info_sp->registers())) {
+ for (auto x : llvm::enumerate(
+ m_reg_info_sp->registers<
+ DynamicRegisterInfo::reg_collection_const_range>())) {
const struct RegisterInfo &reginfo = x.value();
m_reg_valid[x.index()] =
(reginfo.byte_offset + reginfo.byte_size <=
@@ -373,14 +376,8 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
if (dst == nullptr)
return false;
- // Code below is specific to AArch64 target in SVE state
- // If vector granule (vg) register is being written then thread's
- // register context reconfiguration is triggered on success.
- bool do_reconfigure_arm64_sve = false;
- const ArchSpec &arch = process->GetTarget().GetArchitecture();
- if (arch.IsValid() && arch.GetTriple().isAArch64())
- if (strcmp(reg_info->name, "vg") == 0)
- do_reconfigure_arm64_sve = true;
+ const bool should_reconfigure_registers =
+ RegisterWriteCausesReconfigure(reg_info->name);
if (data.CopyByteOrderedData(data_offset, // src offset
reg_info->byte_size, // src length
@@ -400,10 +397,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
{m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
{
- SetAllRegisterValid(false);
+ if (should_reconfigure_registers)
+ ReconfigureRegisterInfo();
- if (do_reconfigure_arm64_sve)
- AArch64SVEReconfigure();
+ InvalidateAllRegisters();
return true;
}
@@ -434,9 +431,6 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
} else {
// This is an actual register, write it
success = SetPrimordialRegister(reg_info, gdb_comm);
-
- if (success && do_reconfigure_arm64_sve)
- AArch64SVEReconfigure();
}
// Check if writing this register will invalidate any other register
@@ -450,6 +444,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
false);
}
+ if (success && should_reconfigure_registers &&
+ ReconfigureRegisterInfo())
+ InvalidateAllRegisters();
+
return success;
}
} else {
@@ -760,58 +758,20 @@ uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);
}
-bool GDBRemoteRegisterContext::AArch64SVEReconfigure() {
- if (!m_reg_info_sp)
- return false;
-
- const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("vg");
- if (!reg_info)
- return false;
-
- uint64_t fail_value = LLDB_INVALID_ADDRESS;
- uint32_t vg_reg_num = reg_info->kinds[eRegisterKindLLDB];
- uint64_t vg_reg_value = ReadRegisterAsUnsigned(vg_reg_num, fail_value);
-
- if (vg_reg_value != fail_value && vg_reg_value <= 32) {
- const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("p0");
- if (!reg_info || vg_reg_value == reg_info->byte_size)
- return false;
-
- if (m_reg_info_sp->UpdateARM64SVERegistersInfos(vg_reg_value)) {
- // Make a heap based buffer that is big enough to store all registers
- m_reg_data.SetData(std::make_shared<DataBufferHeap>(
- m_reg_info_sp->GetRegisterDataByteSize(), 0));
- m_reg_data.SetByteOrder(GetByteOrder());
-
- InvalidateAllRegisters();
-
- return true;
- }
- }
-
- return false;
+bool GDBRemoteRegisterContext::RegisterWriteCausesReconfigure(
+ const llvm::StringRef name) {
+ ExecutionContext exe_ctx(CalculateThread());
+ const Architecture *architecture =
+ exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();
+ return architecture && architecture->RegisterWriteCausesReconfigure(name);
}
-bool GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos(uint64_t vg) {
- // SVE Z register size is vg x 8 bytes.
- uint32_t z_reg_byte_size = vg * 8;
-
- // SVE vector length has changed, accordingly set size of Z, P and FFR
- // registers. Also invalidate register offsets it will be recalculated
- // after SVE register size update.
- for (auto &reg : m_regs) {
- if (reg.value_regs == nullptr) {
- if (reg.name[0] == 'z' && isdigit(reg.name[1]))
- reg.byte_size = z_reg_byte_size;
- else if (reg.name[0] == 'p' && isdigit(reg.name[1]))
- reg.byte_size = vg;
- else if (strcmp(reg.name, "ffr") == 0)
- reg.byte_size = vg;
- }
- reg.byte_offset = LLDB_INVALID_INDEX32;
- }
-
- // Re-calculate register offsets
- ConfigureOffsets();
- return true;
+bool GDBRemoteRegisterContext::ReconfigureRegisterInfo() {
+ ExecutionContext exe_ctx(CalculateThread());
+ const Architecture *architecture =
+ exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();
+ if (architecture)
+ return architecture->ReconfigureRegisterInfo(*(m_reg_info_sp.get()),
+ m_reg_data, *this);
+ return false;
}
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 d185cb5aede1..6a90f911353f 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
@@ -38,7 +38,8 @@ public:
~GDBRemoteDynamicRegisterInfo() override = default;
- bool UpdateARM64SVERegistersInfos(uint64_t vg);
+ void UpdateARM64SVERegistersInfos(uint64_t vg);
+ void UpdateARM64SMERegistersInfos(uint64_t svg);
};
class GDBRemoteRegisterContext : public RegisterContext {
@@ -77,7 +78,9 @@ public:
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
uint32_t num) override;
- bool AArch64SVEReconfigure();
+ bool RegisterWriteCausesReconfigure(const llvm::StringRef name) override;
+
+ bool ReconfigureRegisterInfo() override;
protected:
friend class ThreadGDBRemote;
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 b6f146fd872e..316be471df92 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
@@ -24,11 +24,11 @@
#include <sys/types.h>
#include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Breakpoint/WatchpointResource.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
@@ -36,6 +36,7 @@
#include "lldb/Host/HostThread.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Host/PseudoTerminal.h"
+#include "lldb/Host/StreamFile.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/XML.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -48,7 +49,6 @@
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
-#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
@@ -129,8 +129,8 @@ enum {
class PluginProperties : public Properties {
public:
- static ConstString GetSettingName() {
- return ConstString(ProcessGDBRemote::GetPluginNameStatic());
+ static llvm::StringRef GetSettingName() {
+ return ProcessGDBRemote::GetPluginNameStatic();
}
PluginProperties() : Properties() {
@@ -303,7 +303,7 @@ ProcessGDBRemote::~ProcessGDBRemote() {
// 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();
+ Finalize(true /* destructing */);
// The general Finalize is going to try to destroy the process and that
// SHOULD shut down the async thread. However, if we don't kill it it will
@@ -899,11 +899,8 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
process_arch.GetTriple().getTriple());
}
- if (int addressable_bits = m_gdb_comm.GetAddressingBits()) {
- lldb::addr_t address_mask = ~((1ULL << addressable_bits) - 1);
- SetCodeAddressMask(address_mask);
- SetDataAddressMask(address_mask);
- }
+ AddressableBits addressable_bits = m_gdb_comm.GetAddressableBits();
+ addressable_bits.SetProcessMasks(*this);
if (process_arch.IsValid()) {
const ArchSpec &target_arch = GetTarget().GetArchitecture();
@@ -1001,10 +998,11 @@ void ProcessGDBRemote::LoadStubBinaries() {
const bool force_symbol_search = true;
const bool notify = true;
const bool set_address_in_target = true;
+ const bool allow_memory_image_last_resort = false;
DynamicLoader::LoadBinaryWithUUIDAndAddress(
this, "", standalone_uuid, standalone_value,
standalone_value_is_offset, force_symbol_search, notify,
- set_address_in_target);
+ set_address_in_target, allow_memory_image_last_resort);
}
}
@@ -1033,10 +1031,12 @@ void ProcessGDBRemote::LoadStubBinaries() {
const bool force_symbol_search = true;
const bool set_address_in_target = true;
+ const bool allow_memory_image_last_resort = false;
// Second manually load this binary into the Target.
DynamicLoader::LoadBinaryWithUUIDAndAddress(
this, llvm::StringRef(), uuid, addr, value_is_slide,
- force_symbol_search, notify, set_address_in_target);
+ force_symbol_search, notify, set_address_in_target,
+ allow_memory_image_last_resort);
}
}
}
@@ -1612,6 +1612,22 @@ bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) {
return false;
}
+void ProcessGDBRemote::ParseExpeditedRegisters(
+ ExpeditedRegisterMap &expedited_register_map, ThreadSP thread_sp) {
+ ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread_sp.get());
+ RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext());
+
+ for (const auto &pair : expedited_register_map) {
+ StringExtractor reg_value_extractor(pair.second);
+ WritableDataBufferSP buffer_sp(
+ new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0));
+ reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindProcessPlugin, pair.first);
+ gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData());
+ }
+}
+
ThreadSP ProcessGDBRemote::SetThreadStopInfo(
lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map,
uint8_t signo, const std::string &thread_name, const std::string &reason,
@@ -1642,35 +1658,24 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
}
ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread_sp.get());
- RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext());
+ RegisterContextSP reg_ctx_sp(gdb_thread->GetRegisterContext());
- gdb_reg_ctx_sp->InvalidateIfNeeded(true);
+ reg_ctx_sp->InvalidateIfNeeded(true);
auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid);
if (iter != m_thread_ids.end())
SetThreadPc(thread_sp, iter - m_thread_ids.begin());
- for (const auto &pair : expedited_register_map) {
- StringExtractor reg_value_extractor(pair.second);
- WritableDataBufferSP buffer_sp(
- new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0));
- reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
- 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
- // SVE register sizes and offsets if value of VG register has changed
- // since last stop.
- const ArchSpec &arch = GetTarget().GetArchitecture();
- if (arch.IsValid() && arch.GetTriple().isAArch64()) {
- GDBRemoteRegisterContext *reg_ctx_sp =
- static_cast<GDBRemoteRegisterContext *>(
- gdb_thread->GetRegisterContext().get());
+ ParseExpeditedRegisters(expedited_register_map, thread_sp);
- if (reg_ctx_sp)
- reg_ctx_sp->AArch64SVEReconfigure();
+ if (reg_ctx_sp->ReconfigureRegisterInfo()) {
+ // Now we have changed the offsets of all the registers, so the values
+ // will be corrupted.
+ reg_ctx_sp->InvalidateAllRegisters();
+ // Expedited registers values will never contain registers that would be
+ // resized by a reconfigure. So we are safe to continue using these
+ // values.
+ ParseExpeditedRegisters(expedited_register_map, thread_sp);
}
thread_sp->SetName(thread_name.empty() ? nullptr : thread_name.c_str());
@@ -1785,30 +1790,38 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
// disable/step/re-enable it, so one of the valid watchpoint
// addresses should be provided as \a wp_addr.
StringExtractor desc_extractor(description.c_str());
+ // FIXME NativeThreadLinux::SetStoppedByWatchpoint sends this
+ // up as
+ // <address within wp range> <wp hw index> <actual accessed addr>
+ // but this is not reading the <wp hw index>. Seems like it
+ // wouldn't work on MIPS, where that third field is important.
addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
- uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
bool silently_continue = false;
- WatchpointSP wp_sp;
+ WatchpointResourceSP wp_resource_sp;
if (wp_hit_addr != LLDB_INVALID_ADDRESS) {
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr);
+ wp_resource_sp =
+ m_watchpoint_resource_list.FindByAddress(wp_hit_addr);
// On MIPS, \a wp_hit_addr outside the range of a watched
// region means we should silently continue, it is a false hit.
ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
- if (!wp_sp && core >= ArchSpec::kCore_mips_first &&
+ if (!wp_resource_sp && core >= ArchSpec::kCore_mips_first &&
core <= ArchSpec::kCore_mips_last)
silently_continue = true;
}
- if (!wp_sp && wp_addr != LLDB_INVALID_ADDRESS)
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- if (wp_sp) {
- wp_sp->SetHardwareIndex(wp_index);
- watch_id = wp_sp->GetID();
- }
- if (watch_id == LLDB_INVALID_WATCH_ID) {
+ if (!wp_resource_sp && wp_addr != LLDB_INVALID_ADDRESS)
+ wp_resource_sp = m_watchpoint_resource_list.FindByAddress(wp_addr);
+ if (!wp_resource_sp) {
Log *log(GetLog(GDBRLog::Watchpoints));
LLDB_LOGF(log, "failed to find watchpoint");
+ watch_id = LLDB_INVALID_SITE_ID;
+ } else {
+ // LWP_TODO: This is hardcoding a single Watchpoint in a
+ // Resource, need to add
+ // StopInfo::CreateStopReasonWithWatchpointResource which
+ // represents all watchpoints that were tripped at this stop.
+ watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
}
thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
*thread_sp, watch_id, silently_continue));
@@ -1926,24 +1939,23 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
lldb::ThreadSP
ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
- static ConstString g_key_tid("tid");
- static ConstString g_key_name("name");
- static ConstString g_key_reason("reason");
- static ConstString g_key_metype("metype");
- static ConstString g_key_medata("medata");
- static ConstString g_key_qaddr("qaddr");
- static ConstString g_key_dispatch_queue_t("dispatch_queue_t");
- static ConstString g_key_associated_with_dispatch_queue(
+ static constexpr llvm::StringLiteral g_key_tid("tid");
+ static constexpr llvm::StringLiteral g_key_name("name");
+ static constexpr llvm::StringLiteral g_key_reason("reason");
+ static constexpr llvm::StringLiteral g_key_metype("metype");
+ static constexpr llvm::StringLiteral g_key_medata("medata");
+ static constexpr llvm::StringLiteral g_key_qaddr("qaddr");
+ static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
+ "dispatch_queue_t");
+ static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
"associated_with_dispatch_queue");
- static ConstString g_key_queue_name("qname");
- static ConstString g_key_queue_kind("qkind");
- static ConstString g_key_queue_serial_number("qserialnum");
- static ConstString g_key_registers("registers");
- static ConstString g_key_memory("memory");
- static ConstString g_key_address("address");
- static ConstString g_key_bytes("bytes");
- static ConstString g_key_description("description");
- static ConstString g_key_signal("signal");
+ static constexpr llvm::StringLiteral g_key_queue_name("qname");
+ static constexpr llvm::StringLiteral g_key_queue_kind("qkind");
+ static constexpr llvm::StringLiteral g_key_queue_serial_number("qserialnum");
+ static constexpr llvm::StringLiteral g_key_registers("registers");
+ static constexpr llvm::StringLiteral g_key_memory("memory");
+ static constexpr llvm::StringLiteral g_key_description("description");
+ static constexpr llvm::StringLiteral g_key_signal("signal");
// Stop with signal and thread info
lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
@@ -1971,7 +1983,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
&thread_dispatch_qaddr, &queue_vars_valid,
&associated_with_dispatch_queue, &dispatch_queue_t,
&queue_name, &queue_kind, &queue_serial_number](
- ConstString key,
+ llvm::StringRef key,
StructuredData::Object *object) -> bool {
if (key == g_key_tid) {
// thread in big endian hex
@@ -2029,10 +2041,10 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
if (registers_dict) {
registers_dict->ForEach(
- [&expedited_register_map](ConstString key,
+ [&expedited_register_map](llvm::StringRef key,
StructuredData::Object *object) -> bool {
uint32_t reg;
- if (llvm::to_integer(key.AsCString(), reg))
+ if (llvm::to_integer(key, reg))
expedited_register_map[reg] =
std::string(object->GetStringValue());
return true; // Keep iterating through all array items
@@ -2089,7 +2101,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
switch (stop_type) {
case 'T':
case 'S': {
- // This is a bit of a hack, but is is required. If we did exec, we need to
+ // This is a bit of a hack, but it is required. If we did exec, we need to
// clear our thread lists and also know to rebuild our dynamic register
// info before we lookup and threads and populate the expedited register
// values so we need to know this right away so we can cleanup and update
@@ -2122,6 +2134,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
QueueKind queue_kind = eQueueKindUnknown;
uint64_t queue_serial_number = 0;
ExpeditedRegisterMap expedited_register_map;
+ AddressableBits addressable_bits;
while (stop_packet.GetNameColonValue(key, value)) {
if (key.compare("metype") == 0) {
// exception type in big endian hex
@@ -2232,19 +2245,15 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS;
value.getAsInteger(16, wp_addr);
- WatchpointSP wp_sp =
- GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- uint32_t wp_index = LLDB_INVALID_INDEX32;
-
- if (wp_sp)
- wp_index = wp_sp->GetHardwareIndex();
+ WatchpointResourceSP wp_resource_sp =
+ m_watchpoint_resource_list.FindByAddress(wp_addr);
// Rewrite gdb standard watch/rwatch/awatch to
// "reason:watchpoint" + "description:ADDR",
// which is parsed in SetThreadStopInfo.
reason = "watchpoint";
StreamString ostr;
- ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
+ ostr.Printf("%" PRIu64, wp_addr);
description = std::string(ostr.GetString());
} else if (key.compare("library") == 0) {
auto error = LoadModules();
@@ -2269,9 +2278,17 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
} else if (key.compare("addressing_bits") == 0) {
uint64_t addressing_bits;
if (!value.getAsInteger(0, addressing_bits)) {
- addr_t address_mask = ~((1ULL << addressing_bits) - 1);
- SetCodeAddressMask(address_mask);
- SetDataAddressMask(address_mask);
+ addressable_bits.SetAddressableBits(addressing_bits);
+ }
+ } else if (key.compare("low_mem_addressing_bits") == 0) {
+ uint64_t addressing_bits;
+ if (!value.getAsInteger(0, addressing_bits)) {
+ addressable_bits.SetLowmemAddressableBits(addressing_bits);
+ }
+ } else if (key.compare("high_mem_addressing_bits") == 0) {
+ uint64_t addressing_bits;
+ if (!value.getAsInteger(0, addressing_bits)) {
+ addressable_bits.SetHighmemAddressableBits(addressing_bits);
}
} else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
uint32_t reg = UINT32_MAX;
@@ -2300,6 +2317,8 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
}
}
+ addressable_bits.SetProcessMasks(*this);
+
ThreadSP thread_sp = SetThreadStopInfo(
tid, expedited_register_map, signo, thread_name, reason, description,
exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
@@ -2358,8 +2377,10 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) {
Status error;
if (m_public_state.GetValue() == eStateAttaching) {
- // We are being asked to halt during an attach. We need to just close our
- // file handle and debugserver will go away, and we can be done...
+ // We are being asked to halt during an attach. We used to just close our
+ // file handle and debugserver will go away, but with remote proxies, it
+ // is better to send a positive signal, so let's send the interrupt first...
+ caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout());
m_gdb_comm.Disconnect();
} else
caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout());
@@ -3094,100 +3115,182 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
}
// Pre-requisite: wp != NULL.
-static GDBStoppointType GetGDBStoppointType(Watchpoint *wp) {
- assert(wp);
- bool watch_read = wp->WatchpointRead();
- bool watch_write = wp->WatchpointWrite();
-
- // watch_read and watch_write cannot both be false.
- assert(watch_read || watch_write);
- if (watch_read && watch_write)
+static GDBStoppointType
+GetGDBStoppointType(const WatchpointResourceSP &wp_res_sp) {
+ assert(wp_res_sp);
+ bool read = wp_res_sp->WatchpointResourceRead();
+ bool write = wp_res_sp->WatchpointResourceWrite();
+
+ assert((read || write) &&
+ "WatchpointResource type is neither read nor write");
+ if (read && write)
return eWatchpointReadWrite;
- else if (watch_read)
+ else if (read)
return eWatchpointRead;
- else // Must be watch_write, then.
+ else
return eWatchpointWrite;
}
-Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
+Status ProcessGDBRemote::EnableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
- if (wp) {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log(GetLog(GDBRLog::Watchpoints));
- LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (wp->IsEnabled()) {
- LLDB_LOGF(log,
- "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
- return error;
- }
+ if (!wp_sp) {
+ error.SetErrorString("No watchpoint specified");
+ return error;
+ }
+ user_id_t watchID = wp_sp->GetID();
+ addr_t addr = wp_sp->GetLoadAddress();
+ Log *log(GetLog(GDBRLog::Watchpoints));
+ LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (wp_sp->IsEnabled()) {
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
+ return error;
+ }
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
- wp->GetByteSize(),
- GetInterruptTimeout()) == 0) {
- wp->SetEnabled(true, notify);
- return error;
- } else
- error.SetErrorString("sending gdb watchpoint packet failed");
- } else
- error.SetErrorString("watchpoints not supported");
+ bool read = wp_sp->WatchpointRead();
+ bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
+ size_t size = wp_sp->GetByteSize();
+
+ // New WatchpointResources needed to implement this Watchpoint.
+ std::vector<WatchpointResourceSP> resources;
+
+ // LWP_TODO: Break up the user's request into pieces that can be watched
+ // given the capabilities of the target cpu / stub software.
+ // As a default, breaking the watched region up into target-pointer-sized,
+ // aligned, groups.
+ //
+ // Beyond the default, a stub can / should inform us of its capabilities,
+ // e.g. a stub that can do AArch64 power-of-2 MASK watchpoints.
+ //
+ // And the cpu may have unique capabilities. AArch64 BAS watchpoints
+ // can watch any sequential bytes in a doubleword, but Intel watchpoints
+ // can only watch 1, 2, 4, 8 bytes within a doubleword.
+ WatchpointResourceSP wp_res_sp =
+ std::make_shared<WatchpointResource>(addr, size, read, write);
+ resources.push_back(wp_res_sp);
+
+ // LWP_TODO: Now that we know the WP Resources needed to implement this
+ // Watchpoint, we need to look at currently allocated Resources in the
+ // Process and if they match, or are within the same memory granule, or
+ // overlapping memory ranges, then we need to combine them. e.g. one
+ // Watchpoint watching 1 byte at 0x1002 and a second watchpoint watching 1
+ // byte at 0x1003, they must use the same hardware watchpoint register
+ // (Resource) to watch them.
+
+ // This may mean that an existing resource changes its type (read to
+ // read+write) or address range it is watching, in which case the old
+ // watchpoint needs to be disabled and the new Resource addr/size/type
+ // watchpoint enabled.
+
+ // If we modify a shared Resource to accomodate this newly added Watchpoint,
+ // and we are unable to set all of the Resources for it in the inferior, we
+ // will return an error for this Watchpoint and the shared Resource should
+ // be restored. e.g. this Watchpoint requires three Resources, one which
+ // is shared with another Watchpoint. We extend the shared Resouce to
+ // handle both Watchpoints and we try to set two new ones. But if we don't
+ // have sufficient watchpoint register for all 3, we need to show an error
+ // for creating this Watchpoint and we should reset the shared Resource to
+ // its original configuration because it is no longer shared.
+
+ bool set_all_resources = true;
+ std::vector<WatchpointResourceSP> succesfully_set_resources;
+ for (const auto &wp_res_sp : resources) {
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ if (!m_gdb_comm.SupportsGDBStoppointPacket(type) ||
+ m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, size,
+ GetInterruptTimeout())) {
+ set_all_resources = false;
+ break;
+ } else {
+ succesfully_set_resources.push_back(wp_res_sp);
+ }
+ }
+ if (set_all_resources) {
+ wp_sp->SetEnabled(true, notify);
+ for (const auto &wp_res_sp : resources) {
+ // LWP_TODO: If we expanded/reused an existing Resource,
+ // it's already in the WatchpointResourceList.
+ wp_res_sp->AddConstituent(wp_sp);
+ m_watchpoint_resource_list.Add(wp_res_sp);
+ }
+ return error;
} else {
- error.SetErrorString("Watchpoint argument was NULL.");
+ // We failed to allocate one of the resources. Unset all
+ // of the new resources we did successfully set in the
+ // process.
+ for (const auto &wp_res_sp : succesfully_set_resources) {
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, size,
+ GetInterruptTimeout());
+ }
+ error.SetErrorString("Setting one of the watchpoint resources failed");
}
- if (error.Success())
- error.SetErrorToGenericError();
return error;
}
-Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
+Status ProcessGDBRemote::DisableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
- if (wp) {
- user_id_t watchID = wp->GetID();
+ if (!wp_sp) {
+ error.SetErrorString("Watchpoint argument was NULL.");
+ return error;
+ }
+
+ user_id_t watchID = wp_sp->GetID();
+
+ Log *log(GetLog(GDBRLog::Watchpoints));
- Log *log(GetLog(GDBRLog::Watchpoints));
+ addr_t addr = wp_sp->GetLoadAddress();
- addr_t addr = wp->GetLoadAddress();
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ watchID, (uint64_t)addr);
+ if (!wp_sp->IsEnabled()) {
LLDB_LOGF(log,
"ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64,
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
watchID, (uint64_t)addr);
+ // See also 'class WatchpointSentry' within StopInfo.cpp. This disabling
+ // attempt might come from the user-supplied actions, we'll route it in
+ // order for the watchpoint object to intelligently process this action.
+ wp_sp->SetEnabled(false, notify);
+ return error;
+ }
- if (!wp->IsEnabled()) {
- LLDB_LOGF(log,
- "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
- watchID, (uint64_t)addr);
- // See also 'class WatchpointSentry' within StopInfo.cpp. This disabling
- // attempt might come from the user-supplied actions, we'll route it in
- // order for the watchpoint object to intelligently process this action.
- wp->SetEnabled(false, notify);
- return error;
- }
+ if (wp_sp->IsHardware()) {
+ bool disabled_all = true;
- if (wp->IsHardware()) {
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
- wp->GetByteSize(),
- GetInterruptTimeout()) == 0) {
- wp->SetEnabled(false, notify);
- return error;
- } else
- error.SetErrorString("sending gdb watchpoint packet failed");
+ std::vector<WatchpointResourceSP> unused_resources;
+ for (const auto &wp_res_sp : m_watchpoint_resource_list.Sites()) {
+ if (wp_res_sp->ConstituentsContains(wp_sp)) {
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, size,
+ GetInterruptTimeout())) {
+ disabled_all = false;
+ } else {
+ wp_res_sp->RemoveConstituent(wp_sp);
+ if (wp_res_sp->GetNumberOfConstituents() == 0)
+ unused_resources.push_back(wp_res_sp);
+ }
+ }
}
- // TODO: clear software watchpoints if we implement them
- } else {
- error.SetErrorString("Watchpoint argument was NULL.");
+ for (auto &wp_res_sp : unused_resources)
+ m_watchpoint_resource_list.Remove(wp_res_sp->GetID());
+
+ wp_sp->SetEnabled(false, notify);
+ if (!disabled_all)
+ error.SetErrorString("Failure disabling one of the watchpoint locations");
}
- if (error.Success())
- error.SetErrorToGenericError();
return error;
}
@@ -3368,23 +3471,20 @@ void ProcessGDBRemote::MonitorDebugserverProcess(
if (state != eStateInvalid && state != eStateUnloaded &&
state != eStateExited && state != eStateDetached) {
- char error_str[1024];
- if (signo) {
- const char *signal_cstr =
- process_sp->GetUnixSignals()->GetSignalAsCString(signo);
- if (signal_cstr)
- ::snprintf(error_str, sizeof(error_str),
- DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
+ StreamString stream;
+ if (signo == 0)
+ stream.Format(DEBUGSERVER_BASENAME " died with an exit status of {0:x8}",
+ exit_status);
+ else {
+ llvm::StringRef signal_name =
+ process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
+ const char *format_str = DEBUGSERVER_BASENAME " died with signal {0}";
+ if (!signal_name.empty())
+ stream.Format(format_str, signal_name);
else
- ::snprintf(error_str, sizeof(error_str),
- DEBUGSERVER_BASENAME " died with signal %i", signo);
- } else {
- ::snprintf(error_str, sizeof(error_str),
- DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
- exit_status);
+ stream.Format(format_str, signo);
}
-
- process_sp->SetExitStatus(-1, error_str);
+ process_sp->SetExitStatus(-1, stream.GetString());
}
// Debugserver has exited we need to let our ProcessGDBRemote know that it no
// longer has a debugserver instance
@@ -4372,7 +4472,7 @@ bool ParseRegisters(
// and a simple type. Just in case, look for that too (setting both
// does no harm).
if (!gdb_type.empty() && !(encoding_set || format_set)) {
- if (llvm::StringRef(gdb_type).startswith("int")) {
+ if (llvm::StringRef(gdb_type).starts_with("int")) {
reg_info.format = eFormatHex;
reg_info.encoding = eEncodingUint;
} else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") {
@@ -4382,7 +4482,7 @@ bool ParseRegisters(
reg_info.format = eFormatFloat;
reg_info.encoding = eEncodingIEEE754;
} else if (gdb_type == "aarch64v" ||
- llvm::StringRef(gdb_type).startswith("vec") ||
+ llvm::StringRef(gdb_type).starts_with("vec") ||
gdb_type == "i387_ext" || gdb_type == "uint128") {
// lldb doesn't handle 128-bit uints correctly (for ymm*h), so
// treat them as vector (similarly to xmm/ymm)
@@ -5169,7 +5269,7 @@ public:
Options *GetOptions() override { return &m_option_group; }
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
if (argc == 0) {
ProcessGDBRemote *process =
@@ -5191,14 +5291,13 @@ public:
num_packets, max_send, max_recv, k_recv_amount, json,
output_stream_sp ? *output_stream_sp : result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
+ return;
}
} else {
result.AppendErrorWithFormat("'%s' takes no arguments",
m_cmd_name.c_str());
}
result.SetStatus(eReturnStatusFailed);
- return false;
}
protected:
@@ -5218,16 +5317,15 @@ public:
~CommandObjectProcessGDBRemotePacketHistory() override = default;
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
ProcessGDBRemote *process =
(ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
if (process) {
process->DumpPluginHistory(result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
+ return;
}
result.SetStatus(eReturnStatusFailed);
- return false;
}
};
@@ -5245,14 +5343,14 @@ public:
~CommandObjectProcessGDBRemotePacketXferSize() override = default;
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
if (argc == 0) {
result.AppendErrorWithFormat("'%s' takes an argument to specify the max "
"amount to be transferred when "
"reading/writing",
m_cmd_name.c_str());
- return false;
+ return;
}
ProcessGDBRemote *process =
@@ -5264,11 +5362,10 @@ public:
if (errno == 0 && user_specified_max != 0) {
process->SetUserSpecifiedMaxMemoryTransferSize(user_specified_max);
result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
+ return;
}
}
result.SetStatus(eReturnStatusFailed);
- return false;
}
};
@@ -5289,13 +5386,13 @@ public:
~CommandObjectProcessGDBRemotePacketSend() override = default;
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
if (argc == 0) {
result.AppendErrorWithFormat(
"'%s' takes a one or more packet content arguments",
m_cmd_name.c_str());
- return false;
+ return;
}
ProcessGDBRemote *process =
@@ -5321,7 +5418,6 @@ public:
output_strm.Printf("response: %s\n", response.GetStringRef().data());
}
}
- return true;
}
};
@@ -5338,12 +5434,12 @@ public:
~CommandObjectProcessGDBRemotePacketMonitor() override = default;
- bool DoExecute(llvm::StringRef command,
+ void DoExecute(llvm::StringRef command,
CommandReturnObject &result) override {
if (command.empty()) {
result.AppendErrorWithFormat("'%s' takes a command string argument",
m_cmd_name.c_str());
- return false;
+ return;
}
ProcessGDBRemote *process =
@@ -5367,7 +5463,6 @@ public:
else
output_strm.Printf("response: %s\n", response.GetStringRef().data());
}
- return true;
}
};
@@ -5447,16 +5542,12 @@ void ProcessGDBRemote::DidForkSwitchHardwareTraps(bool enable) {
});
}
- WatchpointList &wps = GetTarget().GetWatchpointList();
- size_t wp_count = wps.GetSize();
- for (size_t i = 0; i < wp_count; ++i) {
- WatchpointSP wp = wps.GetByIndex(i);
- if (wp->IsEnabled()) {
- GDBStoppointType type = GetGDBStoppointType(wp.get());
- m_gdb_comm.SendGDBStoppointTypePacket(type, enable, wp->GetLoadAddress(),
- wp->GetByteSize(),
- GetInterruptTimeout());
- }
+ for (const auto &wp_res_sp : m_watchpoint_resource_list.Sites()) {
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
+ GetInterruptTimeout());
}
}
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 f0ead4c38c23..c1ea1cc79055 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
@@ -158,9 +158,11 @@ public:
Status DisableBreakpointSite(BreakpointSite *bp_site) override;
// Process Watchpoints
- Status EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
+ Status EnableWatchpoint(lldb::WatchpointSP wp_sp,
+ bool notify = true) override;
- Status DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
+ Status DisableWatchpoint(lldb::WatchpointSP wp_sp,
+ bool notify = true) override;
std::optional<uint32_t> GetWatchpointSlotCount() override;
@@ -470,6 +472,9 @@ private:
void DidForkSwitchSoftwareBreakpoints(bool enable);
void DidForkSwitchHardwareTraps(bool enable);
+ void ParseExpeditedRegisters(ExpeditedRegisterMap &expedited_register_map,
+ lldb::ThreadSP thread_sp);
+
// Lists of register fields generated from the remote's target XML.
// Pointers to these RegisterFlags will be set in the register info passed
// back to the upper levels of lldb. Doing so is safe because this class will
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
index d4c3c8b94b7e..520dad062e09 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
@@ -3,7 +3,11 @@ include "../../../../include/lldb/Core/PropertiesBase.td"
let Definition = "processgdbremote" in {
def PacketTimeout: Property<"packet-timeout", "UInt64">,
Global,
+#ifdef LLDB_SANITIZED
+ DefaultUnsignedValue<60>,
+#else
DefaultUnsignedValue<5>,
+#endif
Desc<"Specify the default packet timeout in seconds.">;
def TargetDefinitionFile: Property<"target-definition-file", "FileSpec">,
Global,
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 99d0b54c40f9..b72307c7e4b9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -166,7 +166,7 @@ ProcessMinidump::~ProcessMinidump() {
// 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();
+ Finalize(true /* destructing */);
}
void ProcessMinidump::Initialize() {
@@ -795,12 +795,12 @@ public:
Options *GetOptions() override { return &m_option_group; }
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
if (argc > 0) {
result.AppendErrorWithFormat("'%s' take no arguments, only options",
m_cmd_name.c_str());
- return false;
+ return;
}
SetDefaultOptionsIfNoneAreSet();
@@ -904,9 +904,7 @@ public:
DumpTextStream(StreamType::FacebookThreadName,
"Facebook Thread Name");
if (DumpFacebookLogcat())
- DumpTextStream(StreamType::FacebookLogcat,
- "Facebook Logcat");
- return true;
+ DumpTextStream(StreamType::FacebookLogcat, "Facebook Logcat");
}
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
index 8ae751095c04..58cf8d62fb86 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
@@ -67,13 +67,14 @@ public:
uint8_t v[32 * 16]; // 32 128-bit floating point registers
};
-protected:
enum class Flags : uint32_t {
ARM64_Flag = 0x80000000,
Integer = ARM64_Flag | 0x00000002,
FloatingPoint = ARM64_Flag | 0x00000004,
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint)
};
+
+protected:
Context m_regs;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
index 9592d335eff7..4dffc4f9db0e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
@@ -99,7 +99,7 @@ struct MinidumpContext_x86_32 {
// The next field is included with
// MinidumpContext_x86_32_Flags::ExtendedRegisters
- // It contains vector (MMX/SSE) registers. It it laid out in the
+ // It contains vector (MMX/SSE) registers. It is laid out in the
// format used by the fxsave and fsrstor instructions, so it includes
// a copy of the x87 floating-point registers as well. See FXSAVE in
// "Intel Architecture Software Developer's Manual, Volume 2."
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index e99a2a08bd50..66f861350d14 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -108,10 +108,18 @@ ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp,
ExecutionContext exe_ctx(target_sp, /*get_process=*/false);
// Create process script object
- StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject(
+ auto obj_or_err = GetInterface().CreatePluginObject(
m_scripted_metadata.GetClassName(), exe_ctx,
m_scripted_metadata.GetArgsSP());
+ if (!obj_or_err) {
+ llvm::consumeError(obj_or_err.takeError());
+ error.SetErrorString("Failed to create script object.");
+ return;
+ }
+
+ StructuredData::GenericSP object_sp = *obj_or_err;
+
if (!object_sp || !object_sp->IsValid()) {
error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
__FUNCTION__,
@@ -122,11 +130,17 @@ ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp,
ScriptedProcess::~ScriptedProcess() {
Clear();
+ // If the interface is not valid, we can't call Finalize(). When that happens
+ // it means that the Scripted Process instanciation failed and the
+ // CreateProcess function returns a nullptr, so no one besides this class
+ // should have access to that bogus process object.
+ if (!m_interface_up)
+ return;
// 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();
+ Finalize(true /* destructing */);
}
void ScriptedProcess::Initialize() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
index 684375957d24..88a4ca3b0389 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -56,14 +56,18 @@ ScriptedThread::Create(ScriptedProcess &process,
}
ExecutionContext exe_ctx(process);
- StructuredData::GenericSP owned_script_object_sp =
- scripted_thread_interface->CreatePluginObject(
- thread_class_name, exe_ctx, process.m_scripted_metadata.GetArgsSP(),
- script_object);
+ auto obj_or_err = scripted_thread_interface->CreatePluginObject(
+ thread_class_name, exe_ctx, process.m_scripted_metadata.GetArgsSP(),
+ script_object);
- if (!owned_script_object_sp)
+ if (!obj_or_err) {
+ llvm::consumeError(obj_or_err.takeError());
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Failed to create script object.");
+ }
+
+ StructuredData::GenericSP owned_script_object_sp = *obj_or_err;
+
if (!owned_script_object_sp->IsValid())
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Created script object is invalid.");
@@ -172,8 +176,9 @@ bool ScriptedThread::LoadArtificialStackFrames() {
StackFrameListSP frames = GetStackFrameList();
for (size_t idx = 0; idx < arr_size; idx++) {
- StructuredData::Dictionary *dict;
- if (!arr_sp->GetItemAtIndexAsDictionary(idx, dict) || !dict)
+ std::optional<StructuredData::Dictionary *> maybe_dict =
+ arr_sp->GetItemAtIndexAsDictionary(idx);
+ if (!maybe_dict)
return ScriptedInterface::ErrorWithMessage<bool>(
LLVM_PRETTY_FUNCTION,
llvm::Twine(
@@ -181,6 +186,7 @@ bool ScriptedThread::LoadArtificialStackFrames() {
llvm::Twine(idx) + llvm::Twine(") from stackframe array."))
.str(),
error, LLDBLog::Thread);
+ StructuredData::Dictionary *dict = *maybe_dict;
lldb::addr_t pc;
if (!dict->GetValueForKeyAsInteger("pc", pc))
diff --git a/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp b/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
index aeb54ef9ee24..067768537c06 100644
--- a/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
@@ -60,7 +60,8 @@ CompilerType RegisterTypeBuilderClang::GetRegisterType(
fields_type = type_system->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
- register_type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
+ register_type_name, llvm::to_underlying(clang::TagTypeKind::Struct),
+ lldb::eLanguageTypeC);
type_system->StartTagDeclarationDefinition(fields_type);
// We assume that RegisterFlags has padded and sorted the fields
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 be573cfba610..f50bc61279d0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -11,7 +11,7 @@
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
+#include "lldb/Host/StreamFile.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/Stream.h"
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 bec90b2038e1..7aeee6e40395 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -9,7 +9,6 @@
#include "ScriptInterpreterNone.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
@@ -27,17 +26,19 @@ ScriptInterpreterNone::ScriptInterpreterNone(Debugger &debugger)
ScriptInterpreterNone::~ScriptInterpreterNone() = default;
+static const char *no_interpreter_err_msg =
+ "error: Embedded script interpreter unavailable. LLDB was built without "
+ "scripting language support.\n";
+
bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command,
CommandReturnObject *,
const ExecuteScriptOptions &) {
- m_debugger.GetErrorStream().PutCString(
- "error: there is no embedded script interpreter in this mode.\n");
+ m_debugger.GetErrorStream().PutCString(no_interpreter_err_msg);
return false;
}
void ScriptInterpreterNone::ExecuteInterpreterLoop() {
- m_debugger.GetErrorStream().PutCString(
- "error: there is no embedded script interpreter in this mode.\n");
+ m_debugger.GetErrorStream().PutCString(no_interpreter_err_msg);
}
void ScriptInterpreterNone::Initialize() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
new file mode 100644
index 000000000000..c162c7367c65
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
@@ -0,0 +1,82 @@
+//===-- ScriptedThreadPythonInterface.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/Target/ExecutionContext.h"
+#include "lldb/Utility/Log.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 "OperatingSystemPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+OperatingSystemPythonInterface::OperatingSystemPythonInterface(
+ ScriptInterpreterPythonImpl &interpreter)
+ : OperatingSystemInterface(), ScriptedThreadPythonInterface(interpreter) {}
+
+llvm::Expected<StructuredData::GenericSP>
+OperatingSystemPythonInterface::CreatePluginObject(
+ llvm::StringRef class_name, ExecutionContext &exe_ctx,
+ StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
+ return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr,
+ exe_ctx.GetProcessSP());
+}
+
+StructuredData::DictionarySP
+OperatingSystemPythonInterface::CreateThread(lldb::tid_t tid,
+ lldb::addr_t context) {
+ Status error;
+ StructuredData::DictionarySP dict = Dispatch<StructuredData::DictionarySP>(
+ "create_thread", error, tid, context);
+
+ if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
+ error))
+ return {};
+
+ return dict;
+}
+
+StructuredData::ArraySP OperatingSystemPythonInterface::GetThreadInfo() {
+ Status error;
+ StructuredData::ArraySP arr =
+ Dispatch<StructuredData::ArraySP>("get_thread_info", error);
+
+ if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr,
+ error))
+ return {};
+
+ return arr;
+}
+
+StructuredData::DictionarySP OperatingSystemPythonInterface::GetRegisterInfo() {
+ return ScriptedThreadPythonInterface::GetRegisterInfo();
+}
+
+std::optional<std::string>
+OperatingSystemPythonInterface::GetRegisterContextForTID(lldb::tid_t tid) {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_register_data", error, tid);
+
+ if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
+ error))
+ return {};
+
+ return obj->GetAsString()->GetValue().str();
+}
+
+#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
new file mode 100644
index 000000000000..da7bbf13b1d5
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
@@ -0,0 +1,48 @@
+//===-- OperatingSystemPythonInterface.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_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "ScriptedThreadPythonInterface.h"
+#include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
+#include <optional>
+
+namespace lldb_private {
+class OperatingSystemPythonInterface
+ : virtual public OperatingSystemInterface,
+ virtual public ScriptedThreadPythonInterface {
+public:
+ OperatingSystemPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+
+ llvm::Expected<StructuredData::GenericSP>
+ CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+ StructuredData::DictionarySP args_sp,
+ StructuredData::Generic *script_obj = nullptr) override;
+
+ llvm::SmallVector<llvm::StringLiteral> GetAbstractMethods() const override {
+ return llvm::SmallVector<llvm::StringLiteral>({"get_thread_info"});
+ }
+
+ StructuredData::DictionarySP CreateThread(lldb::tid_t tid,
+ lldb::addr_t context) override;
+
+ StructuredData::ArraySP GetThreadInfo() override;
+
+ StructuredData::DictionarySP GetRegisterInfo() override;
+
+ std::optional<std::string> GetRegisterContextForTID(lldb::tid_t tid) override;
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
index a0c55874c70a..9ba4731032bd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
@@ -14,10 +14,10 @@
#if LLDB_ENABLE_PYTHON
// LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedPlatformPythonInterface.h"
using namespace lldb;
@@ -29,29 +29,15 @@ ScriptedPlatformPythonInterface::ScriptedPlatformPythonInterface(
ScriptInterpreterPythonImpl &interpreter)
: ScriptedPlatformInterface(), ScriptedPythonInterface(interpreter) {}
-StructuredData::GenericSP ScriptedPlatformPythonInterface::CreatePluginObject(
+llvm::Expected<StructuredData::GenericSP>
+ScriptedPlatformPythonInterface::CreatePluginObject(
llvm::StringRef class_name, ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
- if (class_name.empty())
- return {};
-
- StructuredDataImpl args_impl(args_sp);
- std::string error_string;
-
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- lldb::ExecutionContextRefSP exe_ctx_ref_sp =
+ ExecutionContextRefSP exe_ctx_ref_sp =
std::make_shared<ExecutionContextRef>(exe_ctx);
-
- PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject(
- class_name.str().c_str(), m_interpreter.GetDictionaryName(),
- exe_ctx_ref_sp, args_impl, error_string);
-
- m_object_instance_sp =
- StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
-
- return m_object_instance_sp;
+ StructuredDataImpl sd_impl(args_sp);
+ return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
+ exe_ctx_ref_sp, sd_impl);
}
StructuredData::DictionarySP ScriptedPlatformPythonInterface::ListProcesses() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
index 1e3ad9962325..0842d3a00342 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
@@ -6,15 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPLATFORMPYTHONINTERFACE_H
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_PYTHON
#include "ScriptedPythonInterface.h"
-#include "lldb/Interpreter/ScriptedPlatformInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
namespace lldb_private {
class ScriptedPlatformPythonInterface : public ScriptedPlatformInterface,
@@ -22,12 +22,18 @@ class ScriptedPlatformPythonInterface : public ScriptedPlatformInterface,
public:
ScriptedPlatformPythonInterface(ScriptInterpreterPythonImpl &interpreter);
- StructuredData::GenericSP
+ llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(const llvm::StringRef class_name,
ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp,
StructuredData::Generic *script_obj = nullptr) override;
+ llvm::SmallVector<llvm::StringLiteral> GetAbstractMethods() const override {
+ return llvm::SmallVector<llvm::StringLiteral>(
+ {"list_processes", "attach_to_process", "launch_process",
+ "kill_process"});
+ }
+
StructuredData::DictionarySP ListProcesses() override;
StructuredData::DictionarySP GetProcessInfo(lldb::pid_t) override;
@@ -41,4 +47,4 @@ public:
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPLATFORMPYTHONINTERFACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
index 019924fa1971..e86b34d6b930 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
@@ -9,7 +9,7 @@
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_PYTHON
// LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
#endif
#include "lldb/Target/Process.h"
#include "lldb/Utility/Log.h"
@@ -18,8 +18,8 @@
#if LLDB_ENABLE_PYTHON
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedProcessPythonInterface.h"
#include "ScriptedThreadPythonInterface.h"
#include <optional>
@@ -33,29 +33,15 @@ ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
ScriptInterpreterPythonImpl &interpreter)
: ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
-StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
+llvm::Expected<StructuredData::GenericSP>
+ScriptedProcessPythonInterface::CreatePluginObject(
llvm::StringRef class_name, ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
- if (class_name.empty())
- return {};
-
- StructuredDataImpl args_impl(args_sp);
- std::string error_string;
-
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- lldb::ExecutionContextRefSP exe_ctx_ref_sp =
+ ExecutionContextRefSP exe_ctx_ref_sp =
std::make_shared<ExecutionContextRef>(exe_ctx);
-
- PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject(
- class_name.str().c_str(), m_interpreter.GetDictionaryName(),
- exe_ctx_ref_sp, args_impl, error_string);
-
- m_object_instance_sp =
- StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
-
- return m_object_instance_sp;
+ StructuredDataImpl sd_impl(args_sp);
+ return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
+ exe_ctx_ref_sp, sd_impl);
}
StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
@@ -199,7 +185,7 @@ ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
lldb::ScriptedThreadInterfaceSP
ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
- return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
+ return m_interpreter.CreateScriptedThreadInterface();
}
StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
index ff03eab07648..c75caa9340f2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
@@ -6,15 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPROCESSPYTHONINTERFACE_H
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_PYTHON
#include "ScriptedPythonInterface.h"
-#include "lldb/Interpreter/ScriptedProcessInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
#include <optional>
namespace lldb_private {
@@ -23,12 +23,17 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface,
public:
ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter);
- StructuredData::GenericSP
+ llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(const llvm::StringRef class_name,
ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp,
StructuredData::Generic *script_obj = nullptr) override;
+ llvm::SmallVector<llvm::StringLiteral> GetAbstractMethods() const override {
+ return llvm::SmallVector<llvm::StringLiteral>(
+ {"read_memory_at_address", "is_alive", "get_scripted_thread_plugin"});
+ }
+
StructuredData::DictionarySP GetCapabilities() override;
Status Attach(const ProcessAttachInfo &attach_info) override;
@@ -68,4 +73,4 @@ private:
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPROCESSPYTHONINTERFACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
index 1e36a81fde54..6f22503b279c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
@@ -13,9 +13,9 @@
#if LLDB_ENABLE_PYTHON
// LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedPythonInterface.h"
#include <optional>
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 4d0645d18aca..163659234466 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
#if LLDB_ENABLE_PYTHON
@@ -18,12 +18,12 @@
#include <utility>
#include "lldb/Host/Config.h"
-#include "lldb/Interpreter/ScriptedInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedInterface.h"
#include "lldb/Utility/DataBufferHeap.h"
-#include "PythonDataObjects.h"
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../PythonDataObjects.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
namespace lldb_private {
class ScriptInterpreterPythonImpl;
@@ -32,6 +32,196 @@ public:
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter);
~ScriptedPythonInterface() override = default;
+ enum class AbstractMethodCheckerCases {
+ eNotImplemented,
+ eNotAllocated,
+ eNotCallable,
+ eValid
+ };
+
+ llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerCases>>
+ CheckAbstractMethodImplementation(
+ const python::PythonDictionary &class_dict) const {
+
+ using namespace python;
+
+ std::map<llvm::StringLiteral, AbstractMethodCheckerCases> checker;
+#define SET_ERROR_AND_CONTINUE(method_name, error) \
+ { \
+ checker[method_name] = error; \
+ continue; \
+ }
+
+ for (const llvm::StringLiteral &method_name : GetAbstractMethods()) {
+ if (!class_dict.HasKey(method_name))
+ SET_ERROR_AND_CONTINUE(method_name,
+ AbstractMethodCheckerCases::eNotImplemented)
+ auto callable_or_err = class_dict.GetItem(method_name);
+ if (!callable_or_err)
+ SET_ERROR_AND_CONTINUE(method_name,
+ AbstractMethodCheckerCases::eNotAllocated)
+ if (!PythonCallable::Check(callable_or_err.get().get()))
+ SET_ERROR_AND_CONTINUE(method_name,
+ AbstractMethodCheckerCases::eNotCallable)
+ checker[method_name] = AbstractMethodCheckerCases::eValid;
+ }
+
+#undef HANDLE_ERROR
+
+ return checker;
+ }
+
+ template <typename... Args>
+ llvm::Expected<StructuredData::GenericSP>
+ CreatePluginObject(llvm::StringRef class_name,
+ StructuredData::Generic *script_obj, Args... args) {
+ using namespace python;
+ using Locker = ScriptInterpreterPythonImpl::Locker;
+
+ auto create_error = [](std::string message) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(), message);
+ };
+
+ bool has_class_name = !class_name.empty();
+ bool has_interpreter_dict =
+ !(llvm::StringRef(m_interpreter.GetDictionaryName()).empty());
+ if (!has_class_name && !has_interpreter_dict && !script_obj) {
+ if (!has_class_name)
+ return create_error("Missing script class name.");
+ else if (!has_interpreter_dict)
+ return create_error("Invalid script interpreter dictionary.");
+ else
+ return create_error("Missing scripting object.");
+ }
+
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ PythonObject result = {};
+
+ if (script_obj) {
+ result = PythonObject(PyRefType::Borrowed,
+ static_cast<PyObject *>(script_obj->GetValue()));
+ } else {
+ auto dict =
+ PythonModule::MainModule().ResolveName<python::PythonDictionary>(
+ m_interpreter.GetDictionaryName());
+ if (!dict.IsAllocated())
+ return create_error(
+ llvm::formatv("Could not find interpreter dictionary: %s",
+ m_interpreter.GetDictionaryName()));
+
+ auto init =
+ PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
+ class_name, dict);
+ if (!init.IsAllocated())
+ return create_error(llvm::formatv("Could not find script class: %s",
+ class_name.data()));
+
+ std::tuple<Args...> original_args = std::forward_as_tuple(args...);
+ auto transformed_args = TransformArgs(original_args);
+
+ std::string error_string;
+ llvm::Expected<PythonCallable::ArgInfo> arg_info = init.GetArgInfo();
+ if (!arg_info) {
+ llvm::handleAllErrors(
+ arg_info.takeError(),
+ [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
+ [&](const llvm::ErrorInfoBase &E) {
+ error_string.append(E.message());
+ });
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ error_string);
+ }
+
+ llvm::Expected<PythonObject> expected_return_object =
+ create_error("Resulting object is not initialized.");
+
+ std::apply(
+ [&init, &expected_return_object](auto &&...args) {
+ llvm::consumeError(expected_return_object.takeError());
+ expected_return_object = init(args...);
+ },
+ transformed_args);
+
+ if (!expected_return_object)
+ return expected_return_object.takeError();
+ result = expected_return_object.get();
+ }
+
+ if (!result.IsValid())
+ return create_error("Resulting object is not a valid Python Object.");
+ if (!result.HasAttribute("__class__"))
+ return create_error("Resulting object doesn't have '__class__' member.");
+
+ PythonObject obj_class = result.GetAttributeValue("__class__");
+ if (!obj_class.IsValid())
+ return create_error("Resulting class object is not a valid.");
+ if (!obj_class.HasAttribute("__name__"))
+ return create_error(
+ "Resulting object class doesn't have '__name__' member.");
+ PythonString obj_class_name =
+ obj_class.GetAttributeValue("__name__").AsType<PythonString>();
+
+ PythonObject object_class_mapping_proxy =
+ obj_class.GetAttributeValue("__dict__");
+ if (!obj_class.HasAttribute("__dict__"))
+ return create_error(
+ "Resulting object class doesn't have '__dict__' member.");
+
+ PythonCallable dict_converter = PythonModule::BuiltinsModule()
+ .ResolveName("dict")
+ .AsType<PythonCallable>();
+ if (!dict_converter.IsAllocated())
+ return create_error(
+ "Python 'builtins' module doesn't have 'dict' class.");
+
+ PythonDictionary object_class_dict =
+ dict_converter(object_class_mapping_proxy).AsType<PythonDictionary>();
+ if (!object_class_dict.IsAllocated())
+ return create_error("Coudn't create dictionary from resulting object "
+ "class mapping proxy object.");
+
+ auto checker_or_err = CheckAbstractMethodImplementation(object_class_dict);
+ if (!checker_or_err)
+ return checker_or_err.takeError();
+
+ for (const auto &method_checker : *checker_or_err)
+ switch (method_checker.second) {
+ case AbstractMethodCheckerCases::eNotImplemented:
+ LLDB_LOG(GetLog(LLDBLog::Script),
+ "Abstract method {0}.{1} not implemented.",
+ obj_class_name.GetString(), method_checker.first);
+ break;
+ case AbstractMethodCheckerCases::eNotAllocated:
+ LLDB_LOG(GetLog(LLDBLog::Script),
+ "Abstract method {0}.{1} not allocated.",
+ obj_class_name.GetString(), method_checker.first);
+ break;
+ case AbstractMethodCheckerCases::eNotCallable:
+ LLDB_LOG(GetLog(LLDBLog::Script),
+ "Abstract method {0}.{1} not callable.",
+ obj_class_name.GetString(), method_checker.first);
+ break;
+ case AbstractMethodCheckerCases::eValid:
+ LLDB_LOG(GetLog(LLDBLog::Script),
+ "Abstract method {0}.{1} implemented & valid.",
+ obj_class_name.GetString(), method_checker.first);
+ break;
+ }
+
+ for (const auto &method_checker : *checker_or_err)
+ if (method_checker.second != AbstractMethodCheckerCases::eValid)
+ return create_error(
+ llvm::formatv("Abstract method {0}.{1} missing. Enable lldb "
+ "script log for more details.",
+ obj_class_name.GetString(), method_checker.first));
+
+ m_object_instance_sp = StructuredData::GenericSP(
+ new StructuredPythonObject(std::move(result)));
+ return m_object_instance_sp;
+ }
+
protected:
template <typename T = StructuredData::ObjectSP>
T ExtractValueFromPythonObject(python::PythonObject &p, Status &error) {
@@ -83,10 +273,6 @@ protected:
PythonObject py_return = std::move(expected_return_object.get());
- if (!py_return.IsAllocated())
- return ErrorWithMessage<T>(caller_signature, "Returned object is null.",
- error);
-
// Now that we called the python method with the transformed arguments,
// we need to interate again over both the original and transformed
// parameter pack, and transform back the parameter that were passed in
@@ -97,6 +283,8 @@ protected:
caller_signature,
"Couldn't re-assign reference and pointer arguments.", error);
+ if (!py_return.IsAllocated())
+ return {};
return ExtractValueFromPythonObject<T>(py_return, error);
}
@@ -122,6 +310,18 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
+ python::PythonObject Transform(const StructuredDataImpl &arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
+ python::PythonObject Transform(lldb::ExecutionContextRefSP arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
+ python::PythonObject Transform(lldb::ProcessSP arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
python::PythonObject Transform(lldb::ProcessAttachInfoSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
@@ -146,7 +346,6 @@ protected:
original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
}
-
void ReverseTransform(bool &original_arg,
python::PythonObject transformed_arg, Status &error) {
python::PythonBoolean boolean_arg = python::PythonBoolean(
@@ -254,4 +453,4 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
index 5603a1541314..18e268527eb2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
@@ -13,10 +13,10 @@
#if LLDB_ENABLE_PYTHON
// LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedThreadPythonInterface.h"
#include <optional>
@@ -29,37 +29,15 @@ ScriptedThreadPythonInterface::ScriptedThreadPythonInterface(
ScriptInterpreterPythonImpl &interpreter)
: ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {}
-StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
+llvm::Expected<StructuredData::GenericSP>
+ScriptedThreadPythonInterface::CreatePluginObject(
const llvm::StringRef class_name, ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
- if (class_name.empty() && !script_obj)
- return {};
-
- StructuredDataImpl args_impl(args_sp);
- std::string error_string;
-
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- PythonObject ret_val;
-
- if (!script_obj) {
- lldb::ExecutionContextRefSP exe_ctx_ref_sp =
- std::make_shared<ExecutionContextRef>(exe_ctx);
- ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject(
- class_name.str().c_str(), m_interpreter.GetDictionaryName(),
- exe_ctx_ref_sp, args_impl, error_string);
- } else
- ret_val = PythonObject(PyRefType::Borrowed,
- static_cast<PyObject *>(script_obj->GetValue()));
-
- if (!ret_val)
- return {};
-
- m_object_instance_sp =
- StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
-
- return m_object_instance_sp;
+ ExecutionContextRefSP exe_ctx_ref_sp =
+ std::make_shared<ExecutionContextRef>(exe_ctx);
+ StructuredDataImpl sd_impl(args_sp);
+ return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
+ exe_ctx_ref_sp, sd_impl);
}
lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
index eac4941f8814..5676f7f1d675 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
@@ -6,15 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPYTHONINTERFACE_H
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_PYTHON
#include "ScriptedPythonInterface.h"
-#include "lldb/Interpreter/ScriptedProcessInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
#include <optional>
namespace lldb_private {
@@ -23,11 +23,16 @@ class ScriptedThreadPythonInterface : public ScriptedThreadInterface,
public:
ScriptedThreadPythonInterface(ScriptInterpreterPythonImpl &interpreter);
- StructuredData::GenericSP
+ llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp,
StructuredData::Generic *script_obj = nullptr) override;
+ llvm::SmallVector<llvm::StringLiteral> GetAbstractMethods() const override {
+ return llvm::SmallVector<llvm::StringLiteral>(
+ {"get_stop_reason", "get_register_context"});
+ }
+
lldb::tid_t GetThreadID() override;
std::optional<std::string> GetName() override;
@@ -49,4 +54,4 @@ public:
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPYTHONINTERFACE_H
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 eee2f6f5d43f..ea0a1cdff40f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -71,7 +71,9 @@ Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
}
static bool python_is_finalizing() {
-#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
+#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 13) || (PY_MAJOR_VERSION > 3)
+ return Py_IsFinalizing();
+#elif PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
return _Py_Finalizing != nullptr;
#else
return _Py_IsFinalizing();
@@ -661,6 +663,20 @@ bool PythonDictionary::Check(PyObject *py_obj) {
return PyDict_Check(py_obj);
}
+bool PythonDictionary::HasKey(const llvm::Twine &key) const {
+ if (!IsValid())
+ return false;
+
+ PythonString key_object(key.isSingleStringRef() ? key.getSingleStringRef()
+ : key.str());
+
+ if (int res = PyDict_Contains(m_py_obj, key_object.get()) > 0)
+ return res;
+
+ PyErr_Print();
+ return false;
+}
+
uint32_t PythonDictionary::GetSize() const {
if (IsValid())
return PyDict_Size(m_py_obj);
@@ -1344,7 +1360,7 @@ llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
FileSP file_sp;
if (borrowed) {
- // In this case we we don't need to retain the python
+ // In this case we don't need to retain the python
// object at all.
file_sp = std::make_shared<NativeFile>(fd, options.get(), false);
} else {
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 012f16e95e77..82eee76e42b2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -562,6 +562,8 @@ public:
static bool Check(PyObject *py_obj);
+ bool HasKey(const llvm::Twine &key) const;
+
uint32_t GetSize() const;
PythonList GetKeys() const;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 630ab293cf93..7cdd5577919b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -116,12 +116,6 @@ public:
// callbacks. Although these are scripting-language specific, their definition
// depends on the public API.
- static python::PythonObject LLDBSwigPythonCreateScriptedObject(
- const char *python_class_name, const char *session_dictionary_name,
- lldb::ExecutionContextRefSP exe_ctx_sp,
- const lldb_private::StructuredDataImpl &args_impl,
- std::string &error_string);
-
static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
const lldb::StackFrameSP &sb_frame,
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 55b7a73712c4..ef7a2c128a22 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -14,12 +14,14 @@
// LLDB Python header must be included first
#include "lldb-python.h"
+#include "Interfaces/OperatingSystemPythonInterface.h"
+#include "Interfaces/ScriptedPlatformPythonInterface.h"
+#include "Interfaces/ScriptedProcessPythonInterface.h"
+#include "Interfaces/ScriptedThreadPythonInterface.h"
#include "PythonDataObjects.h"
#include "PythonReadline.h"
#include "SWIGPythonBridge.h"
#include "ScriptInterpreterPythonImpl.h"
-#include "ScriptedPlatformPythonInterface.h"
-#include "ScriptedProcessPythonInterface.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBFrame.h"
@@ -177,18 +179,31 @@ private:
return;
#endif
+// `PyEval_ThreadsInitialized` was deprecated in Python 3.9 and removed in
+// Python 3.13. It has been returning `true` always since Python 3.7.
+#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9) || (PY_MAJOR_VERSION < 3)
if (PyEval_ThreadsInitialized()) {
+#else
+ if (true) {
+#endif
Log *log = GetLog(LLDBLog::Script);
m_was_already_initialized = true;
m_gil_state = PyGILState_Ensure();
LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked\n",
m_gil_state == PyGILState_UNLOCKED ? "un" : "");
+
+// `PyEval_InitThreads` was deprecated in Python 3.9 and removed in
+// Python 3.13.
+#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9) || (PY_MAJOR_VERSION < 3)
return;
}
// InitThreads acquires the GIL if it hasn't been called before.
PyEval_InitThreads();
+#else
+ }
+#endif
}
PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
@@ -412,8 +427,6 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_active_io_handler(eIOHandlerNone), m_session_is_active(false),
m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0),
m_command_thread_state(nullptr) {
- m_scripted_platform_interface_up =
- std::make_unique<ScriptedPlatformPythonInterface>(*this);
m_dictionary_name.append("_dict");
StreamString run_string;
@@ -582,10 +595,6 @@ void ScriptInterpreterPythonImpl::LeaveSession() {
// up believing we have no thread state and PyImport_AddModule will crash if
// that is the case - since that seems to only happen when destroying the
// SBDebugger, we can make do without clearing up stdout and stderr
-
- // rdar://problem/11292882
- // When the current thread state is NULL, PyThreadState_Get() issues a fatal
- // error.
if (PyThreadState_GetDict()) {
PythonDictionary &sys_module_dict = GetSysModuleDictionary();
if (sys_module_dict.IsValid()) {
@@ -1519,6 +1528,16 @@ ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() {
return std::make_unique<ScriptedProcessPythonInterface>(*this);
}
+ScriptedThreadInterfaceSP
+ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
+ return std::make_shared<ScriptedThreadPythonInterface>(*this);
+}
+
+OperatingSystemInterfaceSP
+ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() {
+ return std::make_shared<OperatingSystemPythonInterface>(*this);
+}
+
StructuredData::ObjectSP
ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
ScriptObject obj) {
@@ -1530,159 +1549,6 @@ ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
return py_obj.CreateStructuredObject();
}
-StructuredData::GenericSP
-ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject(
- const char *class_name, lldb::ProcessSP process_sp) {
- if (class_name == nullptr || class_name[0] == '\0')
- return StructuredData::GenericSP();
-
- if (!process_sp)
- return StructuredData::GenericSP();
-
- Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- PythonObject ret_val = SWIGBridge::LLDBSWIGPythonCreateOSPlugin(
- class_name, m_dictionary_name.c_str(), process_sp);
-
- return StructuredData::GenericSP(
- new StructuredPythonObject(std::move(ret_val)));
-}
-
-StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
- StructuredData::ObjectSP os_plugin_object_sp) {
- Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
- if (!os_plugin_object_sp)
- return {};
-
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return {};
-
- PythonObject implementor(PyRefType::Borrowed,
- (PyObject *)generic->GetValue());
-
- if (!implementor.IsAllocated())
- return {};
-
- llvm::Expected<PythonObject> expected_py_return =
- implementor.CallMethod("get_register_info");
-
- if (!expected_py_return) {
- llvm::consumeError(expected_py_return.takeError());
- return {};
- }
-
- PythonObject py_return = std::move(expected_py_return.get());
-
- if (py_return.get()) {
- PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
- return result_dict.CreateStructuredDictionary();
- }
- return StructuredData::DictionarySP();
-}
-
-StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
- StructuredData::ObjectSP os_plugin_object_sp) {
- Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- if (!os_plugin_object_sp)
- return {};
-
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return {};
-
- PythonObject implementor(PyRefType::Borrowed,
- (PyObject *)generic->GetValue());
-
- if (!implementor.IsAllocated())
- return {};
-
- llvm::Expected<PythonObject> expected_py_return =
- implementor.CallMethod("get_thread_info");
-
- if (!expected_py_return) {
- llvm::consumeError(expected_py_return.takeError());
- return {};
- }
-
- PythonObject py_return = std::move(expected_py_return.get());
-
- if (py_return.get()) {
- PythonList result_list(PyRefType::Borrowed, py_return.get());
- return result_list.CreateStructuredArray();
- }
- return StructuredData::ArraySP();
-}
-
-StructuredData::StringSP
-ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
- StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
- Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
- if (!os_plugin_object_sp)
- return {};
-
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return {};
- PythonObject implementor(PyRefType::Borrowed,
- (PyObject *)generic->GetValue());
-
- if (!implementor.IsAllocated())
- return {};
-
- llvm::Expected<PythonObject> expected_py_return =
- implementor.CallMethod("get_register_data", tid);
-
- if (!expected_py_return) {
- llvm::consumeError(expected_py_return.takeError());
- return {};
- }
-
- PythonObject py_return = std::move(expected_py_return.get());
-
- if (py_return.get()) {
- PythonBytes result(PyRefType::Borrowed, py_return.get());
- return result.CreateStructuredString();
- }
- return {};
-}
-
-StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
- StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
- lldb::addr_t context) {
- Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
- if (!os_plugin_object_sp)
- return {};
-
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return {};
-
- PythonObject implementor(PyRefType::Borrowed,
- (PyObject *)generic->GetValue());
-
- if (!implementor.IsAllocated())
- return {};
-
- llvm::Expected<PythonObject> expected_py_return =
- implementor.CallMethod("create_thread", tid, context);
-
- if (!expected_py_return) {
- llvm::consumeError(expected_py_return.takeError());
- return {};
- }
-
- PythonObject py_return = std::move(expected_py_return.get());
-
- if (py_return.get()) {
- PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
- return result_dict.CreateStructuredDictionary();
- }
- return StructuredData::DictionarySP();
-}
-
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
const char *class_name, const StructuredDataImpl &args_data,
std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) {
@@ -1783,7 +1649,7 @@ lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
bool
ScriptInterpreterPythonImpl::ScriptedThreadPlanGetStopDescription(
- StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream,
+ StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream,
bool &script_error) {
StructuredData::Generic *generic = nullptr;
if (implementor_sp)
@@ -2442,24 +2308,11 @@ ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName(
}
PythonObject py_return = std::move(expected_py_return.get());
+ if (!py_return.IsAllocated() || !PythonString::Check(py_return.get()))
+ return {};
- ConstString ret_val;
- bool got_string = false;
- std::string buffer;
-
- if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
- PythonString py_string(PyRefType::Borrowed, py_return.get());
- llvm::StringRef return_data(py_string.GetString());
- if (!return_data.empty()) {
- buffer.assign(return_data.data(), return_data.size());
- got_string = true;
- }
- }
-
- if (got_string)
- ret_val.SetCStringWithLength(buffer.c_str(), buffer.size());
-
- return ret_val;
+ PythonString type_name(PyRefType::Borrowed, py_return.get());
+ return ConstString(type_name.GetString());
}
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
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 01db6c520300..a33499816d8d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -134,23 +134,9 @@ public:
lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override;
- StructuredData::GenericSP
- OSPlugin_CreatePluginObject(const char *class_name,
- lldb::ProcessSP process_sp) override;
-
- StructuredData::DictionarySP
- OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
+ lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
- StructuredData::ArraySP
- OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
-
- StructuredData::StringSP
- OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
- lldb::tid_t thread_id) override;
-
- StructuredData::DictionarySP
- OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
- lldb::tid_t tid, lldb::addr_t context) override;
+ lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override;
StructuredData::ObjectSP
LoadPluginModule(const FileSpec &file_spec,
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 a5818915773c..c46dc54c912e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -32,6 +32,8 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
+#include "llvm/ADT/StringMap.h"
+
#define DARWIN_LOG_TYPE_VALUE "DarwinLog"
using namespace lldb;
@@ -117,8 +119,8 @@ enum {
class StructuredDataDarwinLogProperties : public Properties {
public:
- static ConstString &GetSettingName() {
- static ConstString g_setting_name("darwin-log");
+ static llvm::StringRef GetSettingName() {
+ static constexpr llvm::StringLiteral g_setting_name("darwin-log");
return g_setting_name;
}
@@ -183,21 +185,20 @@ public:
std::function<FilterRuleSP(bool accept, size_t attribute_index,
const std::string &op_arg, Status &error)>;
- static void RegisterOperation(ConstString operation,
+ static void RegisterOperation(llvm::StringRef operation,
const OperationCreationFunc &creation_func) {
GetCreationFuncMap().insert(std::make_pair(operation, creation_func));
}
static FilterRuleSP CreateRule(bool match_accepts, size_t attribute,
- ConstString operation,
+ llvm::StringRef operation,
const std::string &op_arg, Status &error) {
// Find the creation func for this type of filter rule.
auto map = GetCreationFuncMap();
auto find_it = map.find(operation);
if (find_it == map.end()) {
- error.SetErrorStringWithFormat("unknown filter operation \""
- "%s\"",
- operation.GetCString());
+ error.SetErrorStringWithFormatv("unknown filter operation \"{0}\"",
+ operation);
return FilterRuleSP();
}
@@ -217,7 +218,7 @@ public:
dict_p->AddStringItem("attribute", s_filter_attributes[m_attribute_index]);
// Indicate the type of the rule.
- dict_p->AddStringItem("type", GetOperationType().GetCString());
+ dict_p->AddStringItem("type", GetOperationType());
// Let the rule add its own specific details here.
DoSerialization(*dict_p);
@@ -227,10 +228,10 @@ public:
virtual void Dump(Stream &stream) const = 0;
- ConstString GetOperationType() const { return m_operation; }
+ llvm::StringRef GetOperationType() const { return m_operation; }
protected:
- FilterRule(bool accept, size_t attribute_index, ConstString operation)
+ FilterRule(bool accept, size_t attribute_index, llvm::StringRef operation)
: m_accept(accept), m_attribute_index(attribute_index),
m_operation(operation) {}
@@ -243,7 +244,7 @@ protected:
}
private:
- using CreationFuncMap = std::map<ConstString, OperationCreationFunc>;
+ using CreationFuncMap = llvm::StringMap<OperationCreationFunc>;
static CreationFuncMap &GetCreationFuncMap() {
static CreationFuncMap s_map;
@@ -252,7 +253,8 @@ private:
const bool m_accept;
const size_t m_attribute_index;
- const ConstString m_operation;
+ // The lifetime of m_operation should be static.
+ const llvm::StringRef m_operation;
};
using FilterRules = std::vector<FilterRuleSP>;
@@ -296,8 +298,8 @@ private:
return FilterRuleSP(new RegexFilterRule(accept, attribute_index, op_arg));
}
- static ConstString StaticGetOperation() {
- static ConstString s_operation("regex");
+ static llvm::StringRef StaticGetOperation() {
+ static constexpr llvm::StringLiteral s_operation("regex");
return s_operation;
}
@@ -341,8 +343,8 @@ private:
new ExactMatchFilterRule(accept, attribute_index, op_arg));
}
- static ConstString StaticGetOperation() {
- static ConstString s_operation("match");
+ static llvm::StringRef StaticGetOperation() {
+ static constexpr llvm::StringLiteral s_operation("match");
return s_operation;
}
@@ -701,7 +703,7 @@ private:
// add filter spec
auto rule_sp = FilterRule::CreateRule(
- accept, attribute_index, ConstString(operation),
+ accept, attribute_index, operation,
std::string(rule_text.substr(operation_end_pos + 1)), error);
if (rule_sp && error.Success())
@@ -764,7 +766,7 @@ protected:
result.AppendWarning(stream.GetString());
}
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
// First off, set the global sticky state of enable/disable based on this
// command execution.
s_is_explicitly_enabled = m_enable;
@@ -788,14 +790,14 @@ protected:
if (!process_sp) {
// No active process, so there is nothing more to do right now.
result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
+ return;
}
// If the process is no longer alive, we can't do this now. We'll catch it
// the next time the process is started up.
if (!process_sp->IsAlive()) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
+ return;
}
// Get the plugin for the process.
@@ -836,7 +838,6 @@ protected:
// one this command is setup to do.
plugin.SetEnabled(m_enable);
}
- return result.Succeeded();
}
Options *GetOptions() override {
@@ -859,7 +860,7 @@ public:
"plugin structured-data darwin-log status") {}
protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override {
+ void DoExecute(Args &command, CommandReturnObject &result) override {
auto &stream = result.GetOutputStream();
// Figure out if we've got a process. If so, we can tell if DarwinLog is
@@ -889,7 +890,7 @@ protected:
if (!options_sp) {
// Nothing more to do.
result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
+ return;
}
// Print filter rules
@@ -922,7 +923,6 @@ protected:
options_sp->GetFallthroughAccepts() ? "accept" : "reject");
result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
}
};
@@ -1254,8 +1254,6 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
return;
}
- const ConstString logging_module_name = ConstString(logging_module_cstr);
-
// We need to see libtrace in the list of modules before we can enable
// tracing for the target process.
bool found_logging_support_module = false;
@@ -1266,7 +1264,7 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
auto &file_spec = module_sp->GetFileSpec();
found_logging_support_module =
- (file_spec.GetFilename() == logging_module_name);
+ (file_spec.GetFilename() == logging_module_cstr);
if (found_logging_support_module)
break;
}
@@ -1276,8 +1274,7 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
"StructuredDataDarwinLog::%s logging module %s "
"has not yet been loaded, can't set a breakpoint "
"yet (process uid %u)",
- __FUNCTION__, logging_module_name.AsCString(),
- process.GetUniqueID());
+ __FUNCTION__, logging_module_cstr, process.GetUniqueID());
return;
}
@@ -1287,8 +1284,7 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
LLDB_LOGF(log,
"StructuredDataDarwinLog::%s post-init hook breakpoint "
"set for logging module %s (process uid %u)",
- __FUNCTION__, logging_module_name.AsCString(),
- process.GetUniqueID());
+ __FUNCTION__, logging_module_cstr, process.GetUniqueID());
// We need to try the enable here as well, which will succeed in the event
// that we're attaching to (rather than launching) the process and the
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 cd52233cc8cc..729d6af02402 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -448,15 +448,6 @@ void SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
// TODO
}
-void SymbolFileBreakpad::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) {}
-
-void SymbolFileBreakpad::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {}
-
void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
Log *log = GetLog(LLDBLog::Symbols);
Module &module = *m_objfile_sp->GetModule();
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 4a01a64202ee..214fbdd3ff3a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -118,15 +118,6 @@ public:
void FindFunctions(const RegularExpression &regex, bool include_inlines,
SymbolContextList &sc_list) override;
- void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
-
llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(lldb::LanguageType language) override {
return llvm::make_error<llvm::StringError>(
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h
new file mode 100644
index 000000000000..c1016b2af0c6
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h
@@ -0,0 +1,203 @@
+//===-- CTFTypes.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_SYMBOLFILE_CTF_CTFTYPES_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_CTFTYPES_H
+
+#include "lldb/lldb-types.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace lldb_private {
+
+struct CTFType {
+ enum Kind : uint32_t {
+ eUnknown = 0,
+ eInteger = 1,
+ eFloat = 2,
+ ePointer = 3,
+ eArray = 4,
+ eFunction = 5,
+ eStruct = 6,
+ eUnion = 7,
+ eEnum = 8,
+ eForward = 9,
+ eTypedef = 10,
+ eVolatile = 11,
+ eConst = 12,
+ eRestrict = 13,
+ eSlice = 14,
+ };
+
+ Kind kind;
+ lldb::user_id_t uid;
+ llvm::StringRef name;
+
+ CTFType(Kind kind, lldb::user_id_t uid, llvm::StringRef name)
+ : kind(kind), uid(uid), name(name) {}
+};
+
+struct CTFInteger : public CTFType {
+ CTFInteger(lldb::user_id_t uid, llvm::StringRef name, uint32_t bits,
+ uint32_t encoding)
+ : CTFType(eInteger, uid, name), bits(bits), encoding(encoding) {}
+
+ static bool classof(const CTFType *T) { return T->kind == eInteger; }
+
+ uint32_t bits;
+ uint32_t encoding;
+};
+
+struct CTFModifier : public CTFType {
+protected:
+ CTFModifier(Kind kind, lldb::user_id_t uid, uint32_t type)
+ : CTFType(kind, uid, ""), type(type) {}
+
+ static bool classof(const CTFType *T) {
+ return T->kind == ePointer || T->kind == eConst || T->kind == eVolatile ||
+ T->kind == eRestrict;
+ }
+
+public:
+ uint32_t type;
+};
+
+struct CTFPointer : public CTFModifier {
+ CTFPointer(lldb::user_id_t uid, uint32_t type)
+ : CTFModifier(ePointer, uid, type) {}
+
+ static bool classof(const CTFType *T) { return T->kind == ePointer; }
+};
+
+struct CTFConst : public CTFModifier {
+ CTFConst(lldb::user_id_t uid, uint32_t type)
+ : CTFModifier(eConst, uid, type) {}
+
+ static bool classof(const CTFType *T) { return T->kind == eConst; }
+};
+
+struct CTFVolatile : public CTFModifier {
+ CTFVolatile(lldb::user_id_t uid, uint32_t type)
+ : CTFModifier(eVolatile, uid, type) {}
+
+ static bool classof(const CTFType *T) { return T->kind == eVolatile; }
+};
+
+struct CTFRestrict : public CTFModifier {
+ CTFRestrict(lldb::user_id_t uid, uint32_t type)
+ : CTFModifier(eRestrict, uid, type) {}
+ static bool classof(const CTFType *T) { return T->kind == eRestrict; }
+};
+
+struct CTFTypedef : public CTFType {
+ CTFTypedef(lldb::user_id_t uid, llvm::StringRef name, uint32_t type)
+ : CTFType(eTypedef, uid, name), type(type) {}
+
+ static bool classof(const CTFType *T) { return T->kind == eTypedef; }
+
+ uint32_t type;
+};
+
+struct CTFArray : public CTFType {
+ CTFArray(lldb::user_id_t uid, llvm::StringRef name, uint32_t type,
+ uint32_t index, uint32_t nelems)
+ : CTFType(eArray, uid, name), type(type), index(index), nelems(nelems) {}
+
+ static bool classof(const CTFType *T) { return T->kind == eArray; }
+
+ uint32_t type;
+ uint32_t index;
+ uint32_t nelems;
+};
+
+struct CTFEnum : public CTFType {
+ struct Value {
+ Value(llvm::StringRef name, uint32_t value) : name(name), value(value){};
+ llvm::StringRef name;
+ uint32_t value;
+ };
+
+ CTFEnum(lldb::user_id_t uid, llvm::StringRef name, uint32_t nelems,
+ uint32_t size, std::vector<Value> values)
+ : CTFType(eEnum, uid, name), nelems(nelems), size(size),
+ values(std::move(values)) {
+ assert(this->values.size() == nelems);
+ }
+
+ static bool classof(const CTFType *T) { return T->kind == eEnum; }
+
+ uint32_t nelems;
+ uint32_t size;
+ std::vector<Value> values;
+};
+
+struct CTFFunction : public CTFType {
+ CTFFunction(lldb::user_id_t uid, llvm::StringRef name, uint32_t nargs,
+ uint32_t return_type, std::vector<uint32_t> args, bool variadic)
+ : CTFType(eFunction, uid, name), nargs(nargs), return_type(return_type),
+ args(std::move(args)), variadic(variadic) {}
+
+ static bool classof(const CTFType *T) { return T->kind == eFunction; }
+
+ uint32_t nargs;
+ uint32_t return_type;
+
+ std::vector<uint32_t> args;
+ bool variadic = false;
+};
+
+struct CTFRecord : public CTFType {
+public:
+ struct Field {
+ Field(llvm::StringRef name, uint32_t type, uint64_t offset)
+ : name(name), type(type), offset(offset) {}
+
+ llvm::StringRef name;
+ uint32_t type;
+ uint64_t offset;
+ };
+
+ CTFRecord(Kind kind, lldb::user_id_t uid, llvm::StringRef name,
+ uint32_t nfields, uint32_t size, std::vector<Field> fields)
+ : CTFType(kind, uid, name), nfields(nfields), size(size),
+ fields(std::move(fields)) {}
+
+ static bool classof(const CTFType *T) {
+ return T->kind == eStruct || T->kind == eUnion;
+ }
+
+ uint32_t nfields;
+ uint32_t size;
+ std::vector<Field> fields;
+};
+
+struct CTFStruct : public CTFRecord {
+ CTFStruct(lldb::user_id_t uid, llvm::StringRef name, uint32_t nfields,
+ uint32_t size, std::vector<Field> fields)
+ : CTFRecord(eStruct, uid, name, nfields, size, std::move(fields)){};
+
+ static bool classof(const CTFType *T) { return T->kind == eStruct; }
+};
+
+struct CTFUnion : public CTFRecord {
+ CTFUnion(lldb::user_id_t uid, llvm::StringRef name, uint32_t nfields,
+ uint32_t size, std::vector<Field> fields)
+ : CTFRecord(eUnion, uid, name, nfields, size, std::move(fields)){};
+
+ static bool classof(const CTFType *T) { return T->kind == eUnion; }
+};
+
+struct CTFForward : public CTFType {
+ CTFForward(lldb::user_id_t uid, llvm::StringRef name)
+ : CTFType(eForward, uid, name) {}
+
+ static bool classof(const CTFType *T) { return T->kind == eForward; }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_CTFTYPES_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
index 88926baa7a6e..d192944bb9d0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
@@ -10,7 +10,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamBuffer.h"
#include "lldb/Host/Config.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -26,6 +25,7 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/StreamBuffer.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -317,31 +317,27 @@ uint32_t GetVLen(uint32_t data) {
static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
-static clang::TagTypeKind TranslateRecordKind(SymbolFileCTF::TypeKind type) {
+static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type) {
switch (type) {
- case SymbolFileCTF::TypeKind::eStruct:
- return clang::TTK_Struct;
- case SymbolFileCTF::TypeKind::eUnion:
- return clang::TTK_Union;
+ case CTFType::Kind::eStruct:
+ return clang::TagTypeKind::Struct;
+ case CTFType::Kind::eUnion:
+ return clang::TagTypeKind::Union;
default:
lldbassert(false && "Invalid record kind!");
- return clang::TTK_Struct;
+ return clang::TagTypeKind::Struct;
}
}
-llvm::Expected<TypeSP> SymbolFileCTF::ParseInteger(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name) {
- const uint32_t vdata = m_data.GetU32(&offset);
- const uint32_t bits = GetBits(vdata);
- const uint32_t encoding = GetEncoding(vdata);
-
- lldb::BasicType basic_type = TypeSystemClang::GetBasicTypeEnumeration(name);
+llvm::Expected<TypeSP>
+SymbolFileCTF::CreateInteger(const CTFInteger &ctf_integer) {
+ lldb::BasicType basic_type =
+ TypeSystemClang::GetBasicTypeEnumeration(ctf_integer.name);
if (basic_type == eBasicTypeInvalid)
return llvm::make_error<llvm::StringError>(
llvm::formatv("unsupported integer type: no corresponding basic clang "
"type for '{0}'",
- name),
+ ctf_integer.name),
llvm::inconvertibleErrorCode());
CompilerType compiler_type = m_ast->GetBasicType(basic_type);
@@ -353,104 +349,98 @@ llvm::Expected<TypeSP> SymbolFileCTF::ParseInteger(lldb::offset_t &offset,
return llvm::make_error<llvm::StringError>(
llvm::formatv(
"Found compiler type for '{0}' but it's not an integer type: {1}",
- name, compiler_type.GetDisplayTypeName().GetStringRef()),
+ ctf_integer.name,
+ compiler_type.GetDisplayTypeName().GetStringRef()),
llvm::inconvertibleErrorCode());
// Make sure the signing matches between the CTF and the compiler type.
- const bool type_is_signed = (encoding & IntEncoding::eSigned);
+ const bool type_is_signed = (ctf_integer.encoding & IntEncoding::eSigned);
if (compiler_type_is_signed != type_is_signed)
return llvm::make_error<llvm::StringError>(
llvm::formatv("Found integer compiler type for {0} but compiler type "
"is {1} and {0} is {2}",
- name, compiler_type_is_signed ? "signed" : "unsigned",
+ ctf_integer.name,
+ compiler_type_is_signed ? "signed" : "unsigned",
type_is_signed ? "signed" : "unsigned"),
llvm::inconvertibleErrorCode());
}
Declaration decl;
- return MakeType(uid, ConstString(name), GetBytes(bits), nullptr,
- LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
- compiler_type, lldb_private::Type::ResolveState::Full);
+ return MakeType(ctf_integer.uid, ConstString(ctf_integer.name),
+ GetBytes(ctf_integer.bits), nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, compiler_type,
+ lldb_private::Type::ResolveState::Full);
}
llvm::Expected<lldb::TypeSP>
-SymbolFileCTF::ParseModifierType(lldb::offset_t &offset, lldb::user_id_t uid,
- uint32_t kind, uint32_t type) {
- TypeSP ref_type = GetTypeForUID(type);
+SymbolFileCTF::CreateModifier(const CTFModifier &ctf_modifier) {
+ Type *ref_type = ResolveTypeUID(ctf_modifier.type);
if (!ref_type)
return llvm::make_error<llvm::StringError>(
- llvm::formatv("Could not find modified type: {0}", type),
+ llvm::formatv("Could not find modified type: {0}", ctf_modifier.type),
llvm::inconvertibleErrorCode());
CompilerType compiler_type;
- switch (kind) {
- case TypeKind::ePointer:
+ switch (ctf_modifier.kind) {
+ case CTFType::ePointer:
compiler_type = ref_type->GetFullCompilerType().GetPointerType();
break;
- case TypeKind::eConst:
+ case CTFType::eConst:
compiler_type = ref_type->GetFullCompilerType().AddConstModifier();
break;
- case TypeKind::eVolatile:
+ case CTFType::eVolatile:
compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier();
break;
- case TypeKind::eRestrict:
+ case CTFType::eRestrict:
compiler_type = ref_type->GetFullCompilerType().AddRestrictModifier();
break;
default:
return llvm::make_error<llvm::StringError>(
- llvm::formatv("ParseModifierType called with unsupported kind: {0}",
- kind),
+ llvm::formatv("ParseModifier called with unsupported kind: {0}",
+ ctf_modifier.kind),
llvm::inconvertibleErrorCode());
}
Declaration decl;
- return MakeType(uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
+ return MakeType(ctf_modifier.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
Type::eEncodingIsUID, decl, compiler_type,
lldb_private::Type::ResolveState::Full);
}
-llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseTypedef(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name,
- uint32_t type) {
- TypeSP underlying_type = GetTypeForUID(type);
+llvm::Expected<lldb::TypeSP>
+SymbolFileCTF::CreateTypedef(const CTFTypedef &ctf_typedef) {
+ Type *underlying_type = ResolveTypeUID(ctf_typedef.type);
if (!underlying_type)
return llvm::make_error<llvm::StringError>(
- llvm::formatv("Could not find typedef underlying type: {0}", type),
+ llvm::formatv("Could not find typedef underlying type: {0}",
+ ctf_typedef.type),
llvm::inconvertibleErrorCode());
CompilerType target_ast_type = underlying_type->GetFullCompilerType();
clang::DeclContext *decl_ctx = m_ast->GetTranslationUnitDecl();
CompilerType ast_typedef = target_ast_type.CreateTypedef(
- name.data(), m_ast->CreateDeclContext(decl_ctx), 0);
+ ctf_typedef.name.data(), m_ast->CreateDeclContext(decl_ctx), 0);
Declaration decl;
- return MakeType(uid, ConstString(name), 0, nullptr, LLDB_INVALID_UID,
- lldb_private::Type::eEncodingIsUID, decl, ast_typedef,
- lldb_private::Type::ResolveState::Full);
+ return MakeType(ctf_typedef.uid, ConstString(ctf_typedef.name), 0, nullptr,
+ LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
+ ast_typedef, lldb_private::Type::ResolveState::Full);
}
-llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseArray(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name) {
- ctf_array_t ctf_array;
- ctf_array.contents = m_data.GetU32(&offset);
- ctf_array.index = m_data.GetU32(&offset);
- ctf_array.nelems = m_data.GetU32(&offset);
-
- TypeSP element_type = GetTypeForUID(ctf_array.contents);
+llvm::Expected<lldb::TypeSP>
+SymbolFileCTF::CreateArray(const CTFArray &ctf_array) {
+ Type *element_type = ResolveTypeUID(ctf_array.type);
if (!element_type)
return llvm::make_error<llvm::StringError>(
- llvm::formatv("Could not find array element type: {0}",
- ctf_array.contents),
+ llvm::formatv("Could not find array element type: {0}", ctf_array.type),
llvm::inconvertibleErrorCode());
std::optional<uint64_t> element_size = element_type->GetByteSize(nullptr);
if (!element_size)
return llvm::make_error<llvm::StringError>(
llvm::formatv("could not get element size of type: {0}",
- ctf_array.contents),
+ ctf_array.type),
llvm::inconvertibleErrorCode());
uint64_t size = ctf_array.nelems * *element_size;
@@ -460,149 +450,256 @@ llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseArray(lldb::offset_t &offset,
/*is_gnu_vector*/ false);
Declaration decl;
- return MakeType(uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
+ return MakeType(ctf_array.uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
Type::eEncodingIsUID, decl, compiler_type,
lldb_private::Type::ResolveState::Full);
}
-llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseEnum(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name,
- uint32_t elements,
- uint32_t size) {
+llvm::Expected<lldb::TypeSP>
+SymbolFileCTF::CreateEnum(const CTFEnum &ctf_enum) {
Declaration decl;
CompilerType enum_type = m_ast->CreateEnumerationType(
- name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,
- m_ast->GetBasicType(eBasicTypeInt),
+ ctf_enum.name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(),
+ decl, m_ast->GetBasicType(eBasicTypeInt),
/*is_scoped=*/false);
- for (uint32_t i = 0; i < elements; ++i) {
- ctf_enum_t ctf_enum;
- ctf_enum.name = m_data.GetU32(&offset);
- ctf_enum.value = m_data.GetU32(&offset);
-
- llvm::StringRef value_name = ReadString(ctf_enum.name);
- const uint32_t value = ctf_enum.value;
-
+ for (const CTFEnum::Value &value : ctf_enum.values) {
Declaration value_decl;
- m_ast->AddEnumerationValueToEnumerationType(enum_type, value_decl,
- value_name.data(), value, size);
+ m_ast->AddEnumerationValueToEnumerationType(
+ enum_type, value_decl, value.name.data(), value.value, ctf_enum.size);
}
+ TypeSystemClang::CompleteTagDeclarationDefinition(enum_type);
- return MakeType(uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
+ return MakeType(ctf_enum.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
Type::eEncodingIsUID, decl, enum_type,
lldb_private::Type::ResolveState::Full);
}
llvm::Expected<lldb::TypeSP>
-SymbolFileCTF::ParseFunction(lldb::offset_t &offset, lldb::user_id_t uid,
- llvm::StringRef name, uint32_t num_args,
- uint32_t type) {
+SymbolFileCTF::CreateFunction(const CTFFunction &ctf_function) {
std::vector<CompilerType> arg_types;
- arg_types.reserve(num_args);
-
- bool is_variadic = false;
- for (uint32_t i = 0; i < num_args; ++i) {
- const uint32_t arg_uid = m_data.GetU32(&offset);
-
- // If the last argument is 0, this is a variadic function.
- if (arg_uid == 0) {
- is_variadic = true;
- break;
- }
-
- if (TypeSP arg_type = GetTypeForUID(arg_uid))
+ for (uint32_t arg : ctf_function.args) {
+ if (Type *arg_type = ResolveTypeUID(arg))
arg_types.push_back(arg_type->GetFullCompilerType());
}
- // If the number of arguments is odd, a single uint32_t of padding is inserted
- // to maintain alignment.
- if (num_args % 2 == 1)
- m_data.GetU32(&offset);
-
- TypeSP ret_type = GetTypeForUID(type);
+ Type *ret_type = ResolveTypeUID(ctf_function.return_type);
if (!ret_type)
return llvm::make_error<llvm::StringError>(
- llvm::formatv("Could not find function return type: {0}", type),
+ llvm::formatv("Could not find function return type: {0}",
+ ctf_function.return_type),
llvm::inconvertibleErrorCode());
CompilerType func_type = m_ast->CreateFunctionType(
ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
- is_variadic, 0, clang::CallingConv::CC_C);
+ ctf_function.variadic, 0, clang::CallingConv::CC_C);
Declaration decl;
- return MakeType(uid, ConstString(name), 0, nullptr, LLDB_INVALID_UID,
- Type::eEncodingIsUID, decl, func_type,
+ return MakeType(ctf_function.uid, ConstString(ctf_function.name), 0, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
lldb_private::Type::ResolveState::Full);
}
llvm::Expected<lldb::TypeSP>
-SymbolFileCTF::ParseRecord(lldb::offset_t &offset, lldb::user_id_t uid,
- llvm::StringRef name, uint32_t kind, uint32_t fields,
- uint32_t size) {
- const clang::TagTypeKind tag_kind =
- TranslateRecordKind(static_cast<TypeKind>(kind));
-
- CompilerType union_type =
- m_ast->CreateRecordType(nullptr, OptionalClangModuleID(), eAccessPublic,
- name.data(), tag_kind, eLanguageTypeC);
-
- m_ast->StartTagDeclarationDefinition(union_type);
- for (uint32_t i = 0; i < fields; ++i) {
- ctf_member_t ctf_member;
- ctf_member.name = m_data.GetU32(&offset);
- ctf_member.type = m_data.GetU32(&offset);
- ctf_member.offset = m_data.GetU16(&offset);
- ctf_member.padding = m_data.GetU16(&offset);
-
- llvm::StringRef member_name = ReadString(ctf_member.name);
- const uint32_t member_type_uid = ctf_member.type;
-
- if (TypeSP member_type = GetTypeForUID(member_type_uid)) {
- const uint32_t member_size =
- member_type->GetByteSize(nullptr).value_or(0);
- TypeSystemClang::AddFieldToRecordType(union_type, member_name,
- member_type->GetFullCompilerType(),
- eAccessPublic, member_size);
+SymbolFileCTF::CreateRecord(const CTFRecord &ctf_record) {
+ const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
+ CompilerType record_type = m_ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), eAccessPublic, ctf_record.name.data(),
+ llvm::to_underlying(tag_kind), eLanguageTypeC);
+ m_compiler_types[record_type.GetOpaqueQualType()] = &ctf_record;
+ Declaration decl;
+ return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
+ nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
+ decl, record_type, lldb_private::Type::ResolveState::Forward);
+}
+
+bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
+ // Check if we have a CTF type for the given incomplete compiler type.
+ auto it = m_compiler_types.find(compiler_type.GetOpaqueQualType());
+ if (it == m_compiler_types.end())
+ return false;
+
+ const CTFType *ctf_type = it->second;
+ assert(ctf_type && "m_compiler_types should only contain valid CTF types");
+
+ // We only support resolving record types.
+ assert(llvm::isa<CTFRecord>(ctf_type));
+
+ // Cast to the appropriate CTF type.
+ const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
+
+ // If any of the fields are incomplete, we cannot complete the type.
+ for (const CTFRecord::Field &field : ctf_record->fields) {
+ if (!ResolveTypeUID(field.type)) {
+ LLDB_LOG(GetLog(LLDBLog::Symbols),
+ "Cannot complete type {0} because field {1} is incomplete",
+ ctf_type->uid, field.type);
+ return false;
}
}
- m_ast->CompleteTagDeclarationDefinition(union_type);
+ // Complete the record type.
+ m_ast->StartTagDeclarationDefinition(compiler_type);
+ for (const CTFRecord::Field &field : ctf_record->fields) {
+ Type *field_type = ResolveTypeUID(field.type);
+ assert(field_type && "field must be complete");
+ const uint32_t field_size = field_type->GetByteSize(nullptr).value_or(0);
+ TypeSystemClang::AddFieldToRecordType(compiler_type, field.name,
+ field_type->GetFullCompilerType(),
+ eAccessPublic, field_size);
+ }
+ m_ast->CompleteTagDeclarationDefinition(compiler_type);
+
+ // Now that the compiler type is complete, we don't need to remember it
+ // anymore and can remove the CTF record type.
+ m_compiler_types.erase(compiler_type.GetOpaqueQualType());
+ m_ctf_types.erase(ctf_type->uid);
+
+ return true;
+}
+
+llvm::Expected<lldb::TypeSP>
+SymbolFileCTF::CreateForward(const CTFForward &ctf_forward) {
+ CompilerType forward_compiler_type = m_ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), eAccessPublic, ctf_forward.name,
+ llvm::to_underlying(clang::TagTypeKind::Struct), eLanguageTypeC);
Declaration decl;
- return MakeType(uid, ConstString(name), size, nullptr, LLDB_INVALID_UID,
- lldb_private::Type::eEncodingIsUID, decl, union_type,
- lldb_private::Type::ResolveState::Full);
+ return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ forward_compiler_type, Type::ResolveState::Forward);
+}
+
+llvm::Expected<TypeSP> SymbolFileCTF::CreateType(CTFType *ctf_type) {
+ if (!ctf_type)
+ return llvm::make_error<llvm::StringError>(
+ "cannot create type for unparsed type", llvm::inconvertibleErrorCode());
+
+ switch (ctf_type->kind) {
+ case CTFType::Kind::eInteger:
+ return CreateInteger(*static_cast<CTFInteger *>(ctf_type));
+ case CTFType::Kind::eConst:
+ case CTFType::Kind::ePointer:
+ case CTFType::Kind::eRestrict:
+ case CTFType::Kind::eVolatile:
+ return CreateModifier(*static_cast<CTFModifier *>(ctf_type));
+ case CTFType::Kind::eTypedef:
+ return CreateTypedef(*static_cast<CTFTypedef *>(ctf_type));
+ case CTFType::Kind::eArray:
+ return CreateArray(*static_cast<CTFArray *>(ctf_type));
+ case CTFType::Kind::eEnum:
+ return CreateEnum(*static_cast<CTFEnum *>(ctf_type));
+ case CTFType::Kind::eFunction:
+ return CreateFunction(*static_cast<CTFFunction *>(ctf_type));
+ case CTFType::Kind::eStruct:
+ case CTFType::Kind::eUnion:
+ return CreateRecord(*static_cast<CTFRecord *>(ctf_type));
+ case CTFType::Kind::eForward:
+ return CreateForward(*static_cast<CTFForward *>(ctf_type));
+ case CTFType::Kind::eUnknown:
+ case CTFType::Kind::eFloat:
+ case CTFType::Kind::eSlice:
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("unsupported type (uid = {0}, name = {1}, kind = {2})",
+ ctf_type->uid, ctf_type->name, ctf_type->kind),
+ llvm::inconvertibleErrorCode());
+ }
}
-llvm::Expected<TypeSP> SymbolFileCTF::ParseType(
- lldb::offset_t &offset, lldb::user_id_t uid, llvm::StringRef name,
- uint32_t kind, uint32_t variable_length, uint32_t type, uint32_t size) {
+llvm::Expected<std::unique_ptr<CTFType>>
+SymbolFileCTF::ParseType(lldb::offset_t &offset, lldb::user_id_t uid) {
+ ctf_stype_t ctf_stype;
+ ctf_stype.name = m_data.GetU32(&offset);
+ ctf_stype.info = m_data.GetU32(&offset);
+ ctf_stype.size = m_data.GetU32(&offset);
+
+ llvm::StringRef name = ReadString(ctf_stype.name);
+ const uint32_t kind = GetKind(ctf_stype.info);
+ const uint32_t variable_length = GetVLen(ctf_stype.info);
+ const uint32_t type = ctf_stype.GetType();
+ const uint32_t size = ctf_stype.GetSize();
+
switch (kind) {
- case TypeKind::eInteger:
- return ParseInteger(offset, uid, name);
+ case TypeKind::eInteger: {
+ const uint32_t vdata = m_data.GetU32(&offset);
+ const uint32_t bits = GetBits(vdata);
+ const uint32_t encoding = GetEncoding(vdata);
+ return std::make_unique<CTFInteger>(uid, name, bits, encoding);
+ }
case TypeKind::eConst:
+ return std::make_unique<CTFConst>(uid, type);
case TypeKind::ePointer:
+ return std::make_unique<CTFPointer>(uid, type);
case TypeKind::eRestrict:
+ return std::make_unique<CTFRestrict>(uid, type);
case TypeKind::eVolatile:
- return ParseModifierType(offset, uid, kind, type);
+ return std::make_unique<CTFVolatile>(uid, type);
case TypeKind::eTypedef:
- return ParseTypedef(offset, uid, name, type);
- case TypeKind::eArray:
- return ParseArray(offset, uid, name);
- case TypeKind::eEnum:
- return ParseEnum(offset, uid, name, variable_length, size);
- case TypeKind::eFunction:
- return ParseFunction(offset, uid, name, variable_length, size);
+ return std::make_unique<CTFTypedef>(uid, name, type);
+ case TypeKind::eArray: {
+ const uint32_t type = m_data.GetU32(&offset);
+ const uint32_t index = m_data.GetU32(&offset);
+ const uint32_t nelems = m_data.GetU32(&offset);
+ return std::make_unique<CTFArray>(uid, name, type, index, nelems);
+ }
+ case TypeKind::eEnum: {
+ std::vector<CTFEnum::Value> values;
+ for (uint32_t i = 0; i < variable_length; ++i) {
+ const uint32_t value_name = m_data.GetU32(&offset);
+ const uint32_t value = m_data.GetU32(&offset);
+ values.emplace_back(ReadString(value_name), value);
+ }
+ return std::make_unique<CTFEnum>(uid, name, variable_length, size, values);
+ }
+ case TypeKind::eFunction: {
+ std::vector<uint32_t> args;
+ bool variadic = false;
+ for (uint32_t i = 0; i < variable_length; ++i) {
+ const uint32_t arg_uid = m_data.GetU32(&offset);
+ // If the last argument is 0, this is a variadic function.
+ if (arg_uid == 0) {
+ variadic = true;
+ break;
+ }
+ args.push_back(arg_uid);
+ }
+ // If the number of arguments is odd, a single uint32_t of padding is
+ // inserted to maintain alignment.
+ if (variable_length % 2 == 1)
+ m_data.GetU32(&offset);
+ return std::make_unique<CTFFunction>(uid, name, variable_length, type, args,
+ variadic);
+ }
case TypeKind::eStruct:
- case TypeKind::eUnion:
- return ParseRecord(offset, uid, name, kind, variable_length, size);
- case TypeKind::eFloat:
+ case TypeKind::eUnion: {
+ std::vector<CTFRecord::Field> fields;
+ for (uint32_t i = 0; i < variable_length; ++i) {
+ const uint32_t field_name = m_data.GetU32(&offset);
+ const uint32_t type = m_data.GetU32(&offset);
+ uint64_t field_offset = 0;
+ if (size < g_ctf_field_threshold) {
+ field_offset = m_data.GetU16(&offset);
+ m_data.GetU16(&offset); // Padding
+ } else {
+ const uint32_t offset_hi = m_data.GetU32(&offset);
+ const uint32_t offset_lo = m_data.GetU32(&offset);
+ field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
+ }
+ fields.emplace_back(ReadString(field_name), type, field_offset);
+ }
+ return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
+ name, variable_length, size, fields);
+ }
case TypeKind::eForward:
- case TypeKind::eSlice:
+ return std::make_unique<CTFForward>(uid, name);
case TypeKind::eUnknown:
+ return std::make_unique<CTFType>(static_cast<CTFType::Kind>(kind), uid,
+ name);
+ case TypeKind::eFloat:
+ case TypeKind::eSlice:
offset += (variable_length * sizeof(uint32_t));
break;
}
+
return llvm::make_error<llvm::StringError>(
llvm::formatv("unsupported type (name = {0}, kind = {1}, vlength = {2})",
name, kind, variable_length),
@@ -627,46 +724,24 @@ size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
lldb::user_id_t type_uid = 1;
while (type_offset < type_offset_end) {
- ctf_stype_t ctf_stype;
- ctf_stype.name = m_data.GetU32(&type_offset);
- ctf_stype.info = m_data.GetU32(&type_offset);
- ctf_stype.size = m_data.GetU32(&type_offset);
-
- llvm::StringRef name = ReadString(ctf_stype.name);
- const uint32_t kind = GetKind(ctf_stype.info);
- const uint32_t variable_length = GetVLen(ctf_stype.info);
- const uint32_t type = ctf_stype.GetType();
- const uint32_t size = ctf_stype.GetSize();
-
- TypeSP type_sp;
- llvm::Expected<TypeSP> type_or_error = ParseType(
- type_offset, type_uid, name, kind, variable_length, type, size);
- if (!type_or_error) {
+ llvm::Expected<std::unique_ptr<CTFType>> type_or_error =
+ ParseType(type_offset, type_uid);
+ if (type_or_error) {
+ m_ctf_types[(*type_or_error)->uid] = std::move(*type_or_error);
+ } else {
LLDB_LOG_ERROR(log, type_or_error.takeError(),
"Failed to parse type {1} at offset {2}: {0}", type_uid,
type_offset);
- } else {
- type_sp = *type_or_error;
- if (log) {
- StreamString ss;
- type_sp->Dump(&ss, true);
- LLDB_LOGV(log, "Adding type {0}: {1}", type_uid,
- llvm::StringRef(ss.GetString()).rtrim());
- }
}
-
- AddTypeForUID(type_uid++, type_sp);
+ type_uid++;
}
- if (log) {
- size_t skipped_types = 0;
- for (auto &type : m_types) {
- if (!type)
- skipped_types++;
- }
- LLDB_LOG(log, "Parsed {0} CTF types ({1} skipped)", m_types.size(),
- skipped_types);
- }
+ LLDB_LOG(log, "Parsed {0} CTF types", m_ctf_types.size());
+
+ for (lldb::user_id_t uid = 1; uid < type_uid; ++uid)
+ ResolveTypeUID(uid);
+
+ LLDB_LOG(log, "Created {0} CTF types", m_types.size());
return m_types.size();
}
@@ -725,12 +800,12 @@ size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
break;
}
- TypeSP arg_type = GetTypeForUID(arg_uid);
+ Type *arg_type = ResolveTypeUID(arg_uid);
arg_types.push_back(arg_type->GetFullCompilerType());
}
if (symbol) {
- TypeSP ret_type = GetTypeForUID(ret_uid);
+ Type *ret_type = ResolveTypeUID(ret_uid);
AddressRange func_range =
AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(),
GetObjectFile()->GetModule()->GetSectionList());
@@ -744,7 +819,7 @@ size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
MakeType(function_type_uid, symbol->GetName(), 0, nullptr,
LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
lldb_private::Type::ResolveState::Full);
- AddTypeForUID(function_type_uid, type_sp);
+ m_types[function_type_uid] = type_sp;
// Create function.
lldb::user_id_t func_uid = m_functions.size();
@@ -814,7 +889,6 @@ size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
if (Symbol *symbol =
symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
Symtab::eVisibilityAny, symbol_idx)) {
-
Variable::RangeList ranges;
ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
@@ -906,42 +980,58 @@ void SymbolFileCTF::AddSymbols(Symtab &symtab) {
// We rely on the existing symbol table to map symbols to type.
}
-void SymbolFileCTF::AddTypeForUID(lldb::user_id_t type_uid, lldb::TypeSP type) {
- assert(type_uid == m_types.size() + 1);
- m_types.emplace_back(type);
-}
+lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
+ auto type_it = m_types.find(type_uid);
+ if (type_it != m_types.end())
+ return type_it->second.get();
-TypeSP SymbolFileCTF::GetTypeForUID(lldb::user_id_t type_uid) {
- if (type_uid > m_types.size())
- return {};
+ auto ctf_type_it = m_ctf_types.find(type_uid);
+ if (ctf_type_it == m_ctf_types.end())
+ return nullptr;
+
+ CTFType *ctf_type = ctf_type_it->second.get();
+ assert(ctf_type && "m_ctf_types should only contain valid CTF types");
+
+ Log *log = GetLog(LLDBLog::Symbols);
- if (type_uid < 1)
+ llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
+ if (!type_or_error) {
+ LLDB_LOG_ERROR(log, type_or_error.takeError(),
+ "Failed to create type for {1}: {0}", ctf_type->uid);
return {};
+ }
- return m_types[type_uid - 1];
-}
+ TypeSP type_sp = *type_or_error;
-lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
- return GetTypeForUID(type_uid).get();
-}
+ if (log) {
+ StreamString ss;
+ type_sp->Dump(&ss, true);
+ LLDB_LOGV(log, "Adding type {0}: {1}", type_sp->GetID(),
+ llvm::StringRef(ss.GetString()).rtrim());
+ }
-void SymbolFileCTF::FindTypes(
- lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) {
+ m_types[type_uid] = type_sp;
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
+ // Except for record types which we'll need to complete later, we don't need
+ // the CTF type anymore.
+ if (!isa<CTFRecord>(ctf_type))
+ m_ctf_types.erase(type_uid);
- size_t matches = 0;
- for (TypeSP type_sp : m_types) {
- if (matches == max_matches)
- break;
+ return type_sp.get();
+}
+
+void SymbolFileCTF::FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) {
+ // Make sure we haven't already searched this SymbolFile before.
+ if (results.AlreadySearched(this))
+ return;
+
+ ConstString name = match.GetTypeBasename();
+ for (TypeSP type_sp : GetTypeList().Types()) {
if (type_sp && type_sp->GetName() == name) {
- types.Insert(type_sp);
- matches++;
+ results.InsertUnique(type_sp);
+ if (results.Done(match))
+ return;
}
}
}
@@ -952,7 +1042,7 @@ void SymbolFileCTF::FindTypesByRegex(
ParseTypes(*m_comp_unit_sp);
size_t matches = 0;
- for (TypeSP type_sp : m_types) {
+ for (TypeSP type_sp : GetTypeList().Types()) {
if (matches == max_matches)
break;
if (type_sp && regex.Execute(type_sp->GetName()))
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
index bdd6dcdc3fda..f111937dbd6e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
@@ -13,6 +13,7 @@
#include <optional>
#include <vector>
+#include "CTFTypes.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -85,9 +86,6 @@ public:
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- lldb::TypeSP GetTypeForUID(lldb::user_id_t type_uid);
- void AddTypeForUID(lldb::user_id_t type_uid, lldb::TypeSP type);
-
Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
std::optional<ArrayInfo> GetDynamicArrayInfoForUID(
lldb::user_id_t type_uid,
@@ -95,7 +93,7 @@ public:
return std::nullopt;
}
- bool CompleteType(CompilerType &compiler_type) override { return false; }
+ bool CompleteType(CompilerType &compiler_type) override;
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
lldb::SymbolContextItem resolve_scope,
@@ -107,12 +105,8 @@ public:
lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override {}
- void
- FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
uint32_t max_matches, lldb_private::TypeMap &types);
@@ -216,60 +210,18 @@ private:
uint32_t GetSize() const { return size; }
};
- struct ctf_member_t {
- uint32_t name;
- uint32_t type;
- uint16_t offset;
- uint16_t padding;
- };
-
- struct ctf_array_t {
- uint32_t contents;
- uint32_t index;
- uint32_t nelems;
- };
-
- struct ctf_enum_t {
- uint32_t name;
- int32_t value;
- };
-
- llvm::Expected<lldb::TypeSP> ParseType(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name, uint32_t kind,
- uint32_t variable_length,
- uint32_t type, uint32_t size);
+ llvm::Expected<std::unique_ptr<CTFType>> ParseType(lldb::offset_t &offset,
+ lldb::user_id_t uid);
- llvm::Expected<lldb::TypeSP> ParseInteger(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name);
-
- llvm::Expected<lldb::TypeSP> ParseModifierType(lldb::offset_t &offset,
- lldb::user_id_t uid,
- uint32_t kind, uint32_t type);
-
- llvm::Expected<lldb::TypeSP> ParseTypedef(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name,
- uint32_t type);
-
- llvm::Expected<lldb::TypeSP>
- ParseArray(lldb::offset_t &offset, lldb::user_id_t uid, llvm::StringRef name);
-
- llvm::Expected<lldb::TypeSP> ParseEnum(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name,
- uint32_t elements, uint32_t size);
-
- llvm::Expected<lldb::TypeSP> ParseFunction(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name,
- uint32_t num_args, uint32_t type);
-
- llvm::Expected<lldb::TypeSP> ParseRecord(lldb::offset_t &offset,
- lldb::user_id_t uid,
- llvm::StringRef name, uint32_t kind,
- uint32_t fields, uint32_t size);
+ llvm::Expected<lldb::TypeSP> CreateType(CTFType *ctf_type);
+ llvm::Expected<lldb::TypeSP> CreateInteger(const CTFInteger &ctf_integer);
+ llvm::Expected<lldb::TypeSP> CreateModifier(const CTFModifier &ctf_modifier);
+ llvm::Expected<lldb::TypeSP> CreateTypedef(const CTFTypedef &ctf_typedef);
+ llvm::Expected<lldb::TypeSP> CreateArray(const CTFArray &ctf_array);
+ llvm::Expected<lldb::TypeSP> CreateEnum(const CTFEnum &ctf_enum);
+ llvm::Expected<lldb::TypeSP> CreateFunction(const CTFFunction &ctf_function);
+ llvm::Expected<lldb::TypeSP> CreateRecord(const CTFRecord &ctf_record);
+ llvm::Expected<lldb::TypeSP> CreateForward(const CTFForward &ctf_forward);
llvm::StringRef ReadString(lldb::offset_t offset) const;
@@ -288,12 +240,24 @@ private:
lldb::CompUnitSP m_comp_unit_sp;
std::optional<ctf_header_t> m_header;
- std::vector<lldb::TypeSP> m_types;
+
+ /// Parsed CTF types.
+ llvm::DenseMap<lldb::user_id_t, std::unique_ptr<CTFType>> m_ctf_types;
+
+ /// Parsed LLDB types.
+ llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;
+
+ /// To complete types, we need a way to map (imcomplete) compiler types back
+ /// to parsed CTF types.
+ llvm::DenseMap<lldb::opaque_compiler_type_t, const CTFType *>
+ m_compiler_types;
+
std::vector<lldb::FunctionSP> m_functions;
std::vector<lldb::VariableSP> m_variables;
static constexpr uint16_t g_ctf_magic = 0xcff1;
static constexpr uint8_t g_ctf_version = 4;
+ static constexpr uint16_t g_ctf_field_threshold = 0x2000;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index 34fb98b5a9b6..33537df4f507 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -18,6 +18,7 @@
using namespace lldb_private;
using namespace lldb;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
Module &module, DWARFDataExtractor apple_names,
@@ -50,13 +51,20 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
extract_and_check(apple_namespaces_table_up);
extract_and_check(apple_types_table_up);
extract_and_check(apple_objc_table_up);
+ assert(apple_names.GetByteSize() == 0 || apple_names.GetSharedDataBuffer());
+ assert(apple_namespaces.GetByteSize() == 0 ||
+ apple_namespaces.GetSharedDataBuffer());
+ assert(apple_types.GetByteSize() == 0 || apple_types.GetSharedDataBuffer());
+ assert(apple_objc.GetByteSize() == 0 || apple_objc.GetSharedDataBuffer());
if (apple_names_table_up || apple_namespaces_table_up ||
apple_types_table_up || apple_objc_table_up)
return std::make_unique<AppleDWARFIndex>(
module, std::move(apple_names_table_up),
std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
- std::move(apple_objc_table_up));
+ std::move(apple_objc_table_up), apple_names.GetSharedDataBuffer(),
+ apple_namespaces.GetSharedDataBuffer(),
+ apple_types.GetSharedDataBuffer(), apple_objc.GetSharedDataBuffer());
return nullptr;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
index 6b948e079895..73de75b583bd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
@@ -12,7 +12,8 @@
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
-namespace lldb_private {
+namespace lldb_private::plugin {
+namespace dwarf {
class AppleDWARFIndex : public DWARFIndex {
public:
static std::unique_ptr<AppleDWARFIndex>
@@ -24,11 +25,19 @@ public:
std::unique_ptr<llvm::AppleAcceleratorTable> apple_names,
std::unique_ptr<llvm::AppleAcceleratorTable> apple_namespaces,
std::unique_ptr<llvm::AppleAcceleratorTable> apple_types,
- std::unique_ptr<llvm::AppleAcceleratorTable> apple_objc)
+ std::unique_ptr<llvm::AppleAcceleratorTable> apple_objc,
+ lldb::DataBufferSP apple_names_storage,
+ lldb::DataBufferSP apple_namespaces_storage,
+ lldb::DataBufferSP apple_types_storage,
+ lldb::DataBufferSP apple_objc_storage)
: DWARFIndex(module), m_apple_names_up(std::move(apple_names)),
m_apple_namespaces_up(std::move(apple_namespaces)),
m_apple_types_up(std::move(apple_types)),
- m_apple_objc_up(std::move(apple_objc)) {}
+ m_apple_objc_up(std::move(apple_objc)),
+ m_apple_names_storage(apple_names_storage),
+ m_apple_namespaces_storage(apple_namespaces_storage),
+ m_apple_types_storage(apple_types_storage),
+ m_apple_objc_storage(apple_objc_storage) {}
void Preload() override {}
@@ -66,6 +75,14 @@ private:
std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_namespaces_up;
std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_types_up;
std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_objc_up;
+ /// The following storage variables hold the data that the apple accelerator
+ /// tables tables above point to.
+ /// {
+ lldb::DataBufferSP m_apple_names_storage;
+ lldb::DataBufferSP m_apple_namespaces_storage;
+ lldb::DataBufferSP m_apple_types_storage;
+ lldb::DataBufferSP m_apple_objc_storage;
+ /// }
/// Search for entries whose name is `name` in `table`, calling `callback` for
/// each match. If `search_for_tag` is provided, ignore entries whose tag is
@@ -77,6 +94,7 @@ private:
std::optional<dw_tag_t> search_for_tag = std::nullopt,
std::optional<uint32_t> search_for_qualhash = std::nullopt);
};
-} // namespace lldb_private
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index 88a5e6027557..163e9f4c081c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -14,6 +14,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
void llvm::format_provider<DIERef>::format(const DIERef &ref, raw_ostream &OS,
StringRef Style) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
index b5a5cfe263f7..ad443aacb46e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -14,6 +14,8 @@
#include <cassert>
#include <optional>
+namespace lldb_private::plugin {
+namespace dwarf {
/// Identifies a DWARF debug info entry within a given Module. It contains three
/// "coordinates":
/// - file_index: identifies the separate stand alone debug info file
@@ -93,7 +95,7 @@ public:
/// \return
/// Returns a valid DIERef if decoding succeeded, std::nullopt if there was
/// unsufficient or invalid values that were decoded.
- static std::optional<DIERef> Decode(const lldb_private::DataExtractor &data,
+ static std::optional<DIERef> Decode(const DataExtractor &data,
lldb::offset_t *offset_ptr);
/// Encode this object into a data encoder object.
@@ -103,7 +105,7 @@ public:
/// \param encoder
/// A data encoder object that serialized bytes will be encoded into.
///
- void Encode(lldb_private::DataEncoder &encoder) const;
+ void Encode(DataEncoder &encoder) const;
static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE;
static constexpr uint64_t k_file_index_bit_size =
@@ -131,10 +133,13 @@ private:
static_assert(sizeof(DIERef) == 8);
typedef std::vector<DIERef> DIEArray;
+} // namespace dwarf
+} // namespace lldb_private::plugin
namespace llvm {
-template<> struct format_provider<DIERef> {
- static void format(const DIERef &ref, raw_ostream &OS, StringRef Style);
+template <> struct format_provider<lldb_private::plugin::dwarf::DIERef> {
+ static void format(const lldb_private::plugin::dwarf::DIERef &ref,
+ raw_ostream &OS, StringRef Style);
};
} // namespace llvm
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp
index a68b7cd110eb..409e9bb37ab2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp
@@ -9,6 +9,7 @@
#include "DWARFASTParser.h"
#include "DWARFAttribute.h"
#include "DWARFDIE.h"
+#include "SymbolFileDWARF.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -18,6 +19,7 @@
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
std::optional<SymbolFile::ArrayInfo>
DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
@@ -99,6 +101,30 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
return array_info;
}
+Type *DWARFASTParser::GetTypeForDIE(const DWARFDIE &die) {
+ if (!die)
+ return nullptr;
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ if (!dwarf)
+ return nullptr;
+
+ DWARFAttributes attributes = die.GetAttributes();
+ if (attributes.Size() == 0)
+ return nullptr;
+
+ DWARFFormValue type_die_form;
+ for (size_t i = 0; i < attributes.Size(); ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+
+ if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
+ return dwarf->ResolveTypeUID(form_value.Reference(), true);
+ }
+
+ return nullptr;
+}
+
AccessType
DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) {
switch (dwarf_accessibility) {
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 18825ae060b1..66db396279e0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -17,53 +17,63 @@
#include "lldb/lldb-enumerations.h"
#include <optional>
-class DWARFDIE;
namespace lldb_private {
class CompileUnit;
class ExecutionContext;
}
+
+namespace lldb_private::plugin {
+namespace dwarf {
+class DWARFDIE;
class SymbolFileDWARF;
class DWARFASTParser {
public:
+ enum class Kind { DWARFASTParserClang };
+ DWARFASTParser(Kind kind) : m_kind(kind) {}
+
virtual ~DWARFASTParser() = default;
- virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
+ virtual lldb::TypeSP ParseTypeFromDWARF(const SymbolContext &sc,
const DWARFDIE &die,
bool *type_is_new_ptr) = 0;
- virtual lldb_private::ConstString
- ConstructDemangledNameFromDWARF(const DWARFDIE &die) = 0;
+ virtual ConstString ConstructDemangledNameFromDWARF(const DWARFDIE &die) = 0;
- virtual lldb_private::Function *
- ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
- const DWARFDIE &die,
- const lldb_private::AddressRange &range) = 0;
+ virtual Function *ParseFunctionFromDWARF(CompileUnit &comp_unit,
+ const DWARFDIE &die,
+ const AddressRange &range) = 0;
- virtual bool
- CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
- lldb_private::CompilerType &compiler_type) = 0;
+ virtual bool CompleteTypeFromDWARF(const DWARFDIE &die, Type *type,
+ CompilerType &compiler_type) = 0;
- virtual lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF(const DWARFDIE &die) = 0;
+ virtual CompilerDecl GetDeclForUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual lldb_private::CompilerDeclContext
+ virtual CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual lldb_private::CompilerDeclContext
+ virtual CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0;
virtual void EnsureAllDIEsInDeclContextHaveBeenParsed(
- lldb_private::CompilerDeclContext decl_context) = 0;
+ CompilerDeclContext decl_context) = 0;
- virtual lldb_private::ConstString
- GetDIEClassTemplateParams(const DWARFDIE &die) = 0;
+ virtual ConstString GetDIEClassTemplateParams(const DWARFDIE &die) = 0;
- static std::optional<lldb_private::SymbolFile::ArrayInfo>
+ static std::optional<SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE &parent_die,
- const lldb_private::ExecutionContext *exe_ctx = nullptr);
+ const ExecutionContext *exe_ctx = nullptr);
+
+ lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
static lldb::AccessType GetAccessTypeFromDWARF(uint32_t dwarf_accessibility);
+
+ Kind GetKind() const { return m_kind; }
+
+private:
+ const Kind m_kind;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H
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 a3ade51e1fe5..334876620249 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -31,6 +31,7 @@
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
+#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Language.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
@@ -60,8 +61,11 @@
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
+
DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast)
- : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
+ : DWARFASTParser(Kind::DWARFASTParserClang), m_ast(ast),
+ m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
DWARFASTParserClang::~DWARFASTParserClang() = default;
@@ -130,6 +134,14 @@ static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) {
return lldb::ModuleSP();
}
+// Returns true if the given artificial field name should be ignored when
+// parsing the DWARF.
+static bool ShouldIgnoreArtificialField(llvm::StringRef FieldName) {
+ return FieldName.starts_with("_vptr$")
+ // gdb emit vtable pointer as "_vptr.classname"
+ || FieldName.starts_with("_vptr.");
+}
+
TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
const DWARFDIE &die,
Log *log) {
@@ -140,17 +152,16 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
// If this type comes from a Clang module, recursively look in the
// DWARF section of the .pcm file in the module cache. Clang
// generates DWO skeleton units as breadcrumbs to find them.
- llvm::SmallVector<CompilerContext, 4> decl_context;
- die.GetDeclContext(decl_context);
- TypeMap pcm_types;
+ std::vector<lldb_private::CompilerContext> die_context = die.GetDeclContext();
+ TypeQuery query(die_context, TypeQueryOptions::e_module_search |
+ TypeQueryOptions::e_find_one);
+ TypeResults results;
// The type in the Clang module must have the same language as the current CU.
- LanguageSet languages;
- 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);
- if (pcm_types.Empty()) {
+ query.AddLanguage(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
+ clang_module_sp->FindTypes(query, results);
+ TypeSP pcm_type_sp = results.GetTypeMap().FirstType();
+ if (!pcm_type_sp) {
// Since this type is defined in one of the Clang modules imported
// by this symbol file, search all of them. Instead of calling
// sym_file->FindTypes(), which would return this again, go straight
@@ -159,24 +170,20 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
// Well-formed clang modules never form cycles; guard against corrupted
// ones by inserting the current file.
- searched_symbol_files.insert(&sym_file);
+ results.AlreadySearched(&sym_file);
sym_file.ForEachExternalModule(
- *sc.comp_unit, searched_symbol_files, [&](Module &module) {
- module.GetSymbolFile()->FindTypes(decl_context, languages,
- searched_symbol_files, pcm_types);
- return pcm_types.GetSize();
+ *sc.comp_unit, results.GetSearchedSymbolFiles(), [&](Module &module) {
+ module.FindTypes(query, results);
+ pcm_type_sp = results.GetTypeMap().FirstType();
+ return !pcm_type_sp;
});
}
- if (!pcm_types.GetSize())
+ if (!pcm_type_sp)
return TypeSP();
// We found a real definition for this type in the Clang module, so lets use
// it and cache the fact that we found a complete type for this die.
- TypeSP pcm_type_sp = pcm_types.GetTypeAtIndex(0);
- if (!pcm_type_sp)
- return TypeSP();
-
lldb_private::CompilerType pcm_type = pcm_type_sp->GetForwardCompilerType();
lldb_private::CompilerType type =
GetClangASTImporter().CopyType(m_ast, pcm_type);
@@ -296,6 +303,10 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
byte_size = form_value.Unsigned();
break;
+ case DW_AT_alignment:
+ alignment = form_value.Unsigned();
+ break;
+
case DW_AT_byte_stride:
byte_stride = form_value.Unsigned();
break;
@@ -519,6 +530,33 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
return UpdateSymbolContextScopeForType(sc, die, type_sp);
}
+static std::optional<uint32_t>
+ExtractDataMemberLocation(DWARFDIE const &die, DWARFFormValue const &form_value,
+ ModuleSP module_sp) {
+ // With DWARF 3 and later, if the value is an integer constant,
+ // this form value is the offset in bytes from the beginning of
+ // the containing entity.
+ if (!form_value.BlockData())
+ return form_value.Unsigned();
+
+ Value initialValue(0);
+ Value memberOffset(0);
+ const DWARFDataExtractor &debug_info_data = die.GetData();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ if (!DWARFExpression::Evaluate(
+ nullptr, // ExecutionContext *
+ nullptr, // RegisterContext *
+ module_sp, DataExtractor(debug_info_data, block_offset, block_length),
+ die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, memberOffset,
+ nullptr)) {
+ return {};
+ }
+
+ return memberOffset.ResolveValue(nullptr).UInt();
+}
+
lldb::TypeSP
DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
const DWARFDIE &die,
@@ -805,9 +843,9 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
CompilerType enumerator_clang_type;
CompilerType clang_type;
- clang_type =
- CompilerType(m_ast.weak_from_this(),
- dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ clang_type = CompilerType(
+ m_ast.weak_from_this(),
+ dwarf->GetForwardDeclDIEToCompilerType().lookup(die.GetDIE()));
if (!clang_type) {
if (attrs.type.IsValid()) {
Type *enumerator_type =
@@ -890,8 +928,9 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes &attrs) {
return clang::CC_C;
}
-TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs) {
+TypeSP
+DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
+ const ParsedDWARFTypeAttributes &attrs) {
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
SymbolFileDWARF *dwarf = die.GetDWARF();
@@ -1000,16 +1039,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
}
if (class_opaque_type) {
- // If accessibility isn't set to anything valid, assume public
- // for now...
- if (attrs.accessibility == eAccessNone)
- attrs.accessibility = eAccessPublic;
-
clang::ObjCMethodDecl *objc_method_decl =
m_ast.AddMethodToObjCObjectType(
class_opaque_type, attrs.name.GetCString(), clang_type,
- attrs.accessibility, attrs.is_artificial, is_variadic,
- attrs.is_objc_direct_call);
+ attrs.is_artificial, is_variadic, attrs.is_objc_direct_call);
type_handled = objc_method_decl != nullptr;
if (type_handled) {
LinkDeclContextToDIE(objc_method_decl, die);
@@ -1023,7 +1056,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
}
}
} else if (is_cxx_method) {
- // Look at the parent of this DIE and see if is is a class or
+ // Look at the parent of this DIE and see if it is a class or
// struct and see if this is actually a C++ method
Type *class_type = dwarf->ResolveType(decl_ctx_die);
if (class_type) {
@@ -1116,14 +1149,15 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
// Neither GCC 4.2 nor clang++ currently set a valid
// accessibility in the DWARF for C++ methods...
// Default to public for now...
- if (attrs.accessibility == eAccessNone)
- attrs.accessibility = eAccessPublic;
+ const auto accessibility = attrs.accessibility == eAccessNone
+ ? eAccessPublic
+ : attrs.accessibility;
clang::CXXMethodDecl *cxx_method_decl =
m_ast.AddMethodToCXXRecordType(
class_opaque_type.GetOpaqueQualType(),
attrs.name.GetCString(), attrs.mangled_name,
- clang_type, attrs.accessibility, attrs.is_virtual,
+ clang_type, accessibility, attrs.is_virtual,
is_static, attrs.is_inline, attrs.is_explicit,
is_attr_used, attrs.is_artificial);
@@ -1171,16 +1205,17 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
class_type->GetFullCompilerType();
// The type for this DIE should have been filled in the
- // function call above
+ // function call above.
Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
return type_ptr->shared_from_this();
}
- // FIXME This is fixing some even uglier behavior but we
- // really need to
- // uniq the methods of each class as well as the class
- // itself. <rdar://problem/11240464>
+ // The previous comment isn't actually true if the class wasn't
+ // resolved using the current method's parent DIE as source
+ // data. We need to ensure that we look up the method correctly
+ // in the class and then link the method's DIE to the unique
+ // CXXMethodDecl appropriately.
type_handled = true;
}
}
@@ -1405,26 +1440,9 @@ void DWARFASTParserClang::ParseInheritance(
encoding_form = form_value;
break;
case DW_AT_data_member_location:
- if (form_value.BlockData()) {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(
- nullptr, nullptr, module_sp,
- DataExtractor(debug_info_data, block_offset, block_length),
- die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
- memberOffset, nullptr)) {
- member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
- }
- } else {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning of
- // the containing entity.
- member_byte_offset = form_value.Unsigned();
- }
+ if (auto maybe_offset =
+ ExtractDataMemberLocation(die, form_value, module_sp))
+ member_byte_offset = *maybe_offset;
break;
case DW_AT_accessibility:
@@ -1624,13 +1642,13 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
int tag_decl_kind = -1;
AccessType default_accessibility = eAccessNone;
if (tag == DW_TAG_structure_type) {
- tag_decl_kind = clang::TTK_Struct;
+ tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Struct);
default_accessibility = eAccessPublic;
} else if (tag == DW_TAG_union_type) {
- tag_decl_kind = clang::TTK_Union;
+ tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Union);
default_accessibility = eAccessPublic;
} else if (tag == DW_TAG_class_type) {
- tag_decl_kind = clang::TTK_Class;
+ tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Class);
default_accessibility = eAccessPrivate;
}
@@ -1749,11 +1767,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
}
}
assert(tag_decl_kind != -1);
- (void)tag_decl_kind;
+ UNUSED_IF_ASSERT_DISABLED(tag_decl_kind);
bool clang_type_was_created = false;
- clang_type =
- CompilerType(m_ast.weak_from_this(),
- dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ clang_type = CompilerType(
+ m_ast.weak_from_this(),
+ dwarf->GetForwardDeclDIEToCompilerType().lookup(die.GetDIE()));
if (!clang_type) {
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, nullptr);
@@ -1851,17 +1869,21 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
die.GetOffset(), attrs.name.GetCString());
}
- // 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) {
+ // Setting authority byte size and alignment for empty structures.
+ //
+ // If the byte size or alignmenet of the record is specified then
+ // overwrite the ones 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 || attrs.alignment) {
clang::RecordDecl *record_decl =
TypeSystemClang::GetAsRecordDecl(clang_type);
if (record_decl) {
ClangASTImporter::LayoutInfo layout;
- layout.bit_size = *attrs.byte_size * 8;
+ layout.bit_size = attrs.byte_size.value_or(0) * 8;
+ layout.alignment = attrs.alignment.value_or(0) * 8;
GetClangASTImporter().SetRecordLayout(record_decl, layout);
}
}
@@ -1883,16 +1905,16 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
// the SymbolFile virtual function
// "SymbolFileDWARF::CompleteType(Type *)" When the definition
// needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ assert(!dwarf->GetForwardDeclCompilerTypeToDIE().count(
ClangUtil::RemoveFastQualifiers(clang_type)
.GetOpaqueQualType()) &&
"Type already in the forward declaration map!");
// Can't assume m_ast.GetSymbolFile() is actually a
// SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
// binaries.
- dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
+ dwarf->GetForwardDeclDIEToCompilerType()[die.GetDIE()] =
clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie().try_emplace(
+ dwarf->GetForwardDeclCompilerTypeToDIE().try_emplace(
ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(),
*die.GetDIERef());
m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
@@ -1916,7 +1938,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
if (record_decl)
record_decl->setArgPassingRestrictions(
- clang::RecordDecl::APK_CannotPassInRegs);
+ clang::RecordArgPassingKind::CannotPassInRegs);
}
return type_sp;
}
@@ -2200,6 +2222,9 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
if (layout_info.bit_size == 0)
layout_info.bit_size =
die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+ if (layout_info.alignment == 0)
+ layout_info.alignment =
+ die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_alignment, 0) * 8;
clang::CXXRecordDecl *record_decl =
m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
@@ -2273,7 +2298,7 @@ CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
clang::Decl *clang_decl = GetClangDeclForDIE(die);
if (clang_decl != nullptr)
return m_ast.GetCompilerDecl(clang_decl);
- return CompilerDecl();
+ return {};
}
CompilerDeclContext
@@ -2281,7 +2306,7 @@ DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die);
if (clang_decl_ctx)
return m_ast.CreateDeclContext(clang_decl_ctx);
- return CompilerDeclContext();
+ return {};
}
CompilerDeclContext
@@ -2290,7 +2315,7 @@ DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
GetClangDeclContextContainingDIE(die, nullptr);
if (clang_decl_ctx)
return m_ast.CreateDeclContext(clang_decl_ctx);
- return CompilerDeclContext();
+ return {};
}
size_t DWARFASTParserClang::ParseChildEnumerators(
@@ -2464,27 +2489,6 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
}
namespace {
-/// Parsed form of all attributes that are relevant for parsing type members.
-struct MemberAttributes {
- explicit MemberAttributes(const DWARFDIE &die, const DWARFDIE &parent_die,
- ModuleSP module_sp);
- const char *name = nullptr;
- /// Indicates how many bits into the word (according to the host endianness)
- /// the low-order bit of the field starts. Can be negative.
- int64_t bit_offset = 0;
- /// Indicates the size of the field in bits.
- size_t bit_size = 0;
- uint64_t data_bit_offset = UINT64_MAX;
- AccessType accessibility = eAccessNone;
- std::optional<uint64_t> byte_size;
- std::optional<DWARFFormValue> const_value_form;
- DWARFFormValue encoding_form;
- /// Indicates the byte offset of the word from the base address of the
- /// structure.
- uint32_t member_byte_offset;
- bool is_artificial = false;
-};
-
/// Parsed form of all attributes that are relevant for parsing Objective-C
/// properties.
struct PropertyAttributes {
@@ -2495,13 +2499,126 @@ struct PropertyAttributes {
/// \see clang::ObjCPropertyAttribute
uint32_t prop_attributes = 0;
};
+
+struct DiscriminantValue {
+ explicit DiscriminantValue(const DWARFDIE &die, ModuleSP module_sp);
+
+ uint32_t byte_offset;
+ uint32_t byte_size;
+ DWARFFormValue type_ref;
+};
+
+struct VariantMember {
+ explicit VariantMember(DWARFDIE &die, ModuleSP module_sp);
+ bool IsDefault() const;
+
+ std::optional<uint32_t> discr_value;
+ DWARFFormValue type_ref;
+ ConstString variant_name;
+ uint32_t byte_offset;
+ ConstString GetName() const;
+};
+
+struct VariantPart {
+ explicit VariantPart(const DWARFDIE &die, const DWARFDIE &parent_die,
+ ModuleSP module_sp);
+
+ std::vector<VariantMember> &members();
+
+ DiscriminantValue &discriminant();
+
+private:
+ std::vector<VariantMember> _members;
+ DiscriminantValue _discriminant;
+};
+
} // namespace
-MemberAttributes::MemberAttributes(const DWARFDIE &die,
- const DWARFDIE &parent_die,
- ModuleSP module_sp) {
- member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
+ConstString VariantMember::GetName() const { return this->variant_name; }
+
+bool VariantMember::IsDefault() const { return !discr_value; }
+
+VariantMember::VariantMember(DWARFDIE &die, lldb::ModuleSP module_sp) {
+ assert(die.Tag() == llvm::dwarf::DW_TAG_variant);
+ this->discr_value =
+ die.GetAttributeValueAsOptionalUnsigned(DW_AT_discr_value);
+
+ for (auto child_die : die.children()) {
+ switch (child_die.Tag()) {
+ case llvm::dwarf::DW_TAG_member: {
+ DWARFAttributes attributes = child_die.GetAttributes();
+ for (std::size_t i = 0; i < attributes.Size(); ++i) {
+ DWARFFormValue form_value;
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_name:
+ variant_name = ConstString(form_value.AsCString());
+ break;
+ case DW_AT_type:
+ type_ref = form_value;
+ break;
+
+ case DW_AT_data_member_location:
+ if (auto maybe_offset =
+ ExtractDataMemberLocation(die, form_value, module_sp))
+ byte_offset = *maybe_offset;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+}
+
+DiscriminantValue::DiscriminantValue(const DWARFDIE &die, ModuleSP module_sp) {
+ auto referenced_die = die.GetReferencedDIE(DW_AT_discr);
+ DWARFAttributes attributes = referenced_die.GetAttributes();
+ for (std::size_t i = 0; i < attributes.Size(); ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_type:
+ type_ref = form_value;
+ break;
+ case DW_AT_data_member_location:
+ if (auto maybe_offset =
+ ExtractDataMemberLocation(die, form_value, module_sp))
+ byte_offset = *maybe_offset;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+VariantPart::VariantPart(const DWARFDIE &die, const DWARFDIE &parent_die,
+ lldb::ModuleSP module_sp)
+ : _members(), _discriminant(die, module_sp) {
+ for (auto child : die.children()) {
+ if (child.Tag() == llvm::dwarf::DW_TAG_variant) {
+ _members.push_back(VariantMember(child, module_sp));
+ }
+ }
+}
+
+std::vector<VariantMember> &VariantPart::members() { return this->_members; }
+
+DiscriminantValue &VariantPart::discriminant() { return this->_discriminant; }
+
+DWARFASTParserClang::MemberAttributes::MemberAttributes(
+ const DWARFDIE &die, const DWARFDIE &parent_die, ModuleSP module_sp) {
DWARFAttributes attributes = die.GetAttributes();
for (size_t i = 0; i < attributes.Size(); ++i) {
const dw_attr_t attr = attributes.AttributeAtIndex(i);
@@ -2530,28 +2647,9 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die,
data_bit_offset = form_value.Unsigned();
break;
case DW_AT_data_member_location:
- if (form_value.BlockData()) {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(
- nullptr, // ExecutionContext *
- nullptr, // RegisterContext *
- module_sp,
- DataExtractor(debug_info_data, block_offset, block_length),
- die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
- memberOffset, nullptr)) {
- member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
- }
- } else {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning of
- // the containing entity.
- member_byte_offset = form_value.Unsigned();
- }
+ if (auto maybe_offset =
+ ExtractDataMemberLocation(die, form_value, module_sp))
+ member_byte_offset = *maybe_offset;
break;
case DW_AT_accessibility:
@@ -2561,6 +2659,9 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die,
case DW_AT_artificial:
is_artificial = form_value.Boolean();
break;
+ case DW_AT_declaration:
+ is_declaration = form_value.Boolean();
+ break;
default:
break;
}
@@ -2739,13 +2840,51 @@ llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue(
return result;
}
+void DWARFASTParserClang::CreateStaticMemberVariable(
+ const DWARFDIE &die, const MemberAttributes &attrs,
+ const lldb_private::CompilerType &class_clang_type) {
+ Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
+ assert(die.Tag() == DW_TAG_member || die.Tag() == DW_TAG_variable);
+
+ Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference());
+
+ if (!var_type)
+ return;
+
+ auto accessibility =
+ attrs.accessibility == eAccessNone ? eAccessPublic : attrs.accessibility;
+
+ CompilerType ct = var_type->GetForwardCompilerType();
+ clang::VarDecl *v = TypeSystemClang::AddVariableToRecordType(
+ class_clang_type, attrs.name, ct, accessibility);
+ if (!v) {
+ LLDB_LOG(log, "Failed to add variable to the record type");
+ return;
+ }
+
+ bool unused;
+ // TODO: Support float/double static members as well.
+ if (!ct.IsIntegerOrEnumerationType(unused) || !attrs.const_value_form)
+ return;
+
+ llvm::Expected<llvm::APInt> const_value_or_err =
+ ExtractIntFromFormValue(ct, *attrs.const_value_form);
+ if (!const_value_or_err) {
+ LLDB_LOG_ERROR(log, const_value_or_err.takeError(),
+ "Failed to add const value to variable {1}: {0}",
+ v->getQualifiedNameAsString());
+ return;
+ }
+
+ TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);
+}
+
void DWARFASTParserClang::ParseSingleMember(
const DWARFDIE &die, const DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
lldb::AccessType default_accessibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
FieldInfo &last_field_info) {
- Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
// This function can only parse DW_TAG_member.
assert(die.Tag() == DW_TAG_member);
@@ -2757,49 +2896,22 @@ void DWARFASTParserClang::ParseSingleMember(
const uint64_t parent_bit_size =
parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
- // FIXME: Remove the workarounds below and make this const.
- MemberAttributes attrs(die, parent_die, module_sp);
-
- const bool class_is_objc_object_or_interface =
- TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type);
-
- // FIXME: Make Clang ignore Objective-C accessibility for expressions
- if (class_is_objc_object_or_interface)
- attrs.accessibility = eAccessNone;
+ const MemberAttributes attrs(die, parent_die, module_sp);
- // Handle static members, which is any member that doesn't have a bit or a
- // byte member offset.
+ // Handle static members, which are typically members without
+ // locations. However, GCC doesn't emit DW_AT_data_member_location
+ // for any union members (regardless of linkage).
+ // Non-normative text pre-DWARFv5 recommends marking static
+ // data members with an DW_AT_external flag. Clang emits this consistently
+ // whereas GCC emits it only for static data members if not part of an
+ // anonymous namespace. The flag that is consistently emitted for static
+ // data members is DW_AT_declaration, so we check it instead.
+ // The following block is only necessary to support DWARFv4 and earlier.
+ // Starting with DWARFv5, static data members are marked DW_AT_variable so we
+ // can consistently detect them on both GCC and Clang without below heuristic.
if (attrs.member_byte_offset == UINT32_MAX &&
- attrs.data_bit_offset == UINT64_MAX) {
- Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference());
-
- if (var_type) {
- if (attrs.accessibility == eAccessNone)
- attrs.accessibility = eAccessPublic;
- CompilerType ct = var_type->GetForwardCompilerType();
- clang::VarDecl *v = TypeSystemClang::AddVariableToRecordType(
- class_clang_type, attrs.name, ct, attrs.accessibility);
- if (!v) {
- LLDB_LOG(log, "Failed to add variable to the record type");
- return;
- }
-
- bool unused;
- // TODO: Support float/double static members as well.
- if (!attrs.const_value_form || !ct.IsIntegerOrEnumerationType(unused))
- return;
-
- llvm::Expected<llvm::APInt> const_value_or_err =
- ExtractIntFromFormValue(ct, *attrs.const_value_form);
- if (!const_value_or_err) {
- LLDB_LOG_ERROR(log, const_value_or_err.takeError(),
- "Failed to add const value to variable {1}: {0}",
- v->getQualifiedNameAsString());
- return;
- }
-
- TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);
- }
+ attrs.data_bit_offset == UINT64_MAX && attrs.is_declaration) {
+ CreateStaticMemberVariable(die, attrs, class_clang_type);
return;
}
@@ -2822,8 +2934,9 @@ void DWARFASTParserClang::ParseSingleMember(
const uint64_t word_width = 32;
CompilerType member_clang_type = member_type->GetLayoutCompilerType();
- if (attrs.accessibility == eAccessNone)
- attrs.accessibility = default_accessibility;
+ const auto accessibility = attrs.accessibility == eAccessNone
+ ? default_accessibility
+ : attrs.accessibility;
uint64_t field_bit_offset = (attrs.member_byte_offset == UINT32_MAX
? 0
@@ -2837,12 +2950,13 @@ void DWARFASTParserClang::ParseSingleMember(
if (attrs.data_bit_offset != UINT64_MAX) {
this_field_info.bit_offset = attrs.data_bit_offset;
} else {
- if (!attrs.byte_size)
- attrs.byte_size = member_type->GetByteSize(nullptr);
+ auto byte_size = attrs.byte_size;
+ if (!byte_size)
+ byte_size = member_type->GetByteSize(nullptr);
ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
if (objfile->GetByteOrder() == eByteOrderLittle) {
- this_field_info.bit_offset += attrs.byte_size.value_or(0) * 8;
+ this_field_info.bit_offset += byte_size.value_or(0) * 8;
this_field_info.bit_offset -= (attrs.bit_offset + attrs.bit_size);
} else {
this_field_info.bit_offset += attrs.bit_offset;
@@ -2881,7 +2995,7 @@ void DWARFASTParserClang::ParseSingleMember(
// unnamed bitfields if we have a new enough clang.
bool detect_unnamed_bitfields = true;
- if (class_is_objc_object_or_interface)
+ if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type))
detect_unnamed_bitfields =
die.GetCU()->Supports_unnamed_objc_bitfields();
@@ -2913,7 +3027,7 @@ void DWARFASTParserClang::ParseSingleMember(
class_clang_type, llvm::StringRef(),
m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
word_width),
- attrs.accessibility, unnamed_field_info->bit_size);
+ accessibility, unnamed_field_info->bit_size);
layout_info.field_offsets.insert(std::make_pair(
unnamed_bitfield_decl, unnamed_field_info->bit_offset));
@@ -2937,11 +3051,9 @@ void DWARFASTParserClang::ParseSingleMember(
// in our AST. Clang will re-create those articial members and they would
// otherwise just overlap in the layout with the FieldDecls we add here.
// This needs to be done after updating FieldInfo which keeps track of where
- // field start/end so we don't later try to fill the the space of this
+ // field start/end so we don't later try to fill the space of this
// artificial member with (unnamed bitfield) padding.
- // FIXME: This check should verify that this is indeed an artificial member
- // we are supposed to ignore.
- if (attrs.is_artificial) {
+ if (attrs.is_artificial && ShouldIgnoreArtificialField(attrs.name)) {
last_field_info.SetIsArtificial(true);
return;
}
@@ -2950,12 +3062,10 @@ void DWARFASTParserClang::ParseSingleMember(
member_clang_type.GetCompleteType();
{
- // Older versions of clang emit array[0] and array[1] in the
- // same way (<rdar://problem/12566646>). If the current field
- // is at the end of the structure, then there is definitely no
- // room for extra elements and we override the type to
- // array[0].
-
+ // Older versions of clang emit the same DWARF for array[0] and array[1]. If
+ // the current field is at the end of the structure, then there is
+ // definitely no room for extra elements and we override the type to
+ // array[0]. This was fixed by f454dfb6b5af.
CompilerType member_array_element_type;
uint64_t member_array_size;
bool member_array_is_incomplete;
@@ -2987,7 +3097,7 @@ void DWARFASTParserClang::ParseSingleMember(
TypeSystemClang::RequireCompleteType(member_clang_type);
clang::FieldDecl *field_decl = TypeSystemClang::AddFieldToRecordType(
- class_clang_type, attrs.name, member_clang_type, attrs.accessibility,
+ class_clang_type, attrs.name, member_clang_type, accessibility,
attrs.bit_size);
m_ast.SetMetadataAsUserID(field_decl, die.GetID());
@@ -3022,6 +3132,17 @@ bool DWARFASTParserClang::ParseChildMembers(
ParseObjCProperty(die, parent_die, class_clang_type, delayed_properties);
break;
+ case DW_TAG_variant_part:
+ if (die.GetCU()->GetDWARFLanguageType() == eLanguageTypeRust) {
+ ParseRustVariantPart(die, parent_die, class_clang_type,
+ default_accessibility, layout_info);
+ }
+ break;
+
+ case DW_TAG_variable: {
+ const MemberAttributes attrs(die, parent_die, module_sp);
+ CreateStaticMemberVariable(die, attrs, class_clang_type);
+ } break;
case DW_TAG_member:
ParseSingleMember(die, parent_die, class_clang_type,
default_accessibility, layout_info, last_field_info);
@@ -3167,30 +3288,6 @@ size_t DWARFASTParserClang::ParseChildParameters(
return arg_idx;
}
-Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {
- if (!die)
- return nullptr;
-
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (!dwarf)
- return nullptr;
-
- DWARFAttributes attributes = die.GetAttributes();
- if (attributes.Size() == 0)
- return nullptr;
-
- DWARFFormValue type_die_form;
- for (size_t i = 0; i < attributes.Size(); ++i) {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
-
- if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
- return dwarf->ResolveTypeUID(form_value.Reference(), true);
- }
-
- return nullptr;
-}
-
clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
if (!die)
return nullptr;
@@ -3566,7 +3663,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
// Make sure this is a declaration and not a concrete instance by looking
// for DW_AT_declaration set to 1. Sometimes concrete function instances are
// placed inside the class definitions and shouldn't be included in the list
- // of things are are tracking here.
+ // of things that are tracking here.
if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) != 1)
return;
@@ -3729,3 +3826,77 @@ bool DWARFASTParserClang::ShouldCreateUnnamedBitfield(
return true;
}
+
+void DWARFASTParserClang::ParseRustVariantPart(
+ DWARFDIE &die, const DWARFDIE &parent_die, CompilerType &class_clang_type,
+ const lldb::AccessType default_accesibility,
+ ClangASTImporter::LayoutInfo &layout_info) {
+ assert(die.Tag() == llvm::dwarf::DW_TAG_variant_part);
+ assert(SymbolFileDWARF::GetLanguage(*die.GetCU()) ==
+ LanguageType::eLanguageTypeRust);
+
+ ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
+
+ VariantPart variants(die, parent_die, module_sp);
+
+ auto discriminant_type =
+ die.ResolveTypeUID(variants.discriminant().type_ref.Reference());
+
+ auto decl_context = m_ast.GetDeclContextForType(class_clang_type);
+
+ auto inner_holder = m_ast.CreateRecordType(
+ decl_context, OptionalClangModuleID(), lldb::eAccessPublic,
+ std::string(
+ llvm::formatv("{0}$Inner", class_clang_type.GetTypeName(false))),
+ llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeRust);
+ m_ast.StartTagDeclarationDefinition(inner_holder);
+ m_ast.SetIsPacked(inner_holder);
+
+ for (auto member : variants.members()) {
+
+ auto has_discriminant = !member.IsDefault();
+
+ auto member_type = die.ResolveTypeUID(member.type_ref.Reference());
+
+ auto field_type = m_ast.CreateRecordType(
+ m_ast.GetDeclContextForType(inner_holder), OptionalClangModuleID(),
+ lldb::eAccessPublic,
+ std::string(llvm::formatv("{0}$Variant", member.GetName())),
+ llvm::to_underlying(clang::TagTypeKind::Struct),
+ lldb::eLanguageTypeRust);
+
+ m_ast.StartTagDeclarationDefinition(field_type);
+ auto offset = member.byte_offset;
+
+ if (has_discriminant) {
+ m_ast.AddFieldToRecordType(
+ field_type, "$discr$", discriminant_type->GetFullCompilerType(),
+ lldb::eAccessPublic, variants.discriminant().byte_offset);
+ offset += discriminant_type->GetByteSize(nullptr).value_or(0);
+ }
+
+ m_ast.AddFieldToRecordType(field_type, "value",
+ member_type->GetFullCompilerType(),
+ lldb::eAccessPublic, offset * 8);
+
+ m_ast.CompleteTagDeclarationDefinition(field_type);
+
+ auto name = has_discriminant
+ ? llvm::formatv("$variant${0}", member.discr_value.value())
+ : std::string("$variant$");
+
+ auto variant_decl =
+ m_ast.AddFieldToRecordType(inner_holder, llvm::StringRef(name),
+ field_type, default_accesibility, 0);
+
+ layout_info.field_offsets.insert({variant_decl, 0});
+ }
+
+ auto inner_field = m_ast.AddFieldToRecordType(class_clang_type,
+ llvm::StringRef("$variants$"),
+ inner_holder, eAccessPublic, 0);
+
+ m_ast.CompleteTagDeclarationDefinition(inner_holder);
+
+ layout_info.field_offsets.insert({inner_field, 0});
+}
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 042075b7df5f..3e28e54d6220 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -31,45 +31,51 @@
namespace lldb_private {
class CompileUnit;
}
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFDebugInfoEntry;
class SymbolFileDWARF;
+} // namespace dwarf
+} // namespace lldb_private::plugin
struct ParsedDWARFTypeAttributes;
-class DWARFASTParserClang : public DWARFASTParser {
+class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
public:
DWARFASTParserClang(lldb_private::TypeSystemClang &ast);
~DWARFASTParserClang() override;
// DWARFASTParser interface.
- lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- bool *type_is_new_ptr) override;
+ lldb::TypeSP
+ ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ bool *type_is_new_ptr) override;
- lldb_private::ConstString
- ConstructDemangledNameFromDWARF(const DWARFDIE &die) override;
+ lldb_private::ConstString ConstructDemangledNameFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
lldb_private::Function *
ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
- const DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
const lldb_private::AddressRange &func_range) override;
bool
- CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ CompleteTypeFromDWARF(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) override;
- lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
+ lldb_private::CompilerDecl GetDeclForUIDFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
void EnsureAllDIEsInDeclContextHaveBeenParsed(
lldb_private::CompilerDeclContext decl_context) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext GetDeclContextForUIDFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext GetDeclContextContainingUIDFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
lldb_private::ClangASTImporter &GetClangASTImporter();
@@ -85,9 +91,9 @@ public:
/// DWARFFormValue with the bit width of the given integer type.
/// Returns an error if the value in the DWARFFormValue does not fit
/// into the given integer type or the integer type isn't supported.
- llvm::Expected<llvm::APInt>
- ExtractIntFromFormValue(const lldb_private::CompilerType &int_type,
- const DWARFFormValue &form_value) const;
+ llvm::Expected<llvm::APInt> ExtractIntFromFormValue(
+ const lldb_private::CompilerType &int_type,
+ const lldb_private::plugin::dwarf::DWARFFormValue &form_value) const;
/// Returns the template parameters of a class DWARFDIE as a string.
///
@@ -99,8 +105,8 @@ public:
/// \return A string, including surrounding '<>', of the template parameters.
/// If the DIE's name already has '<>', returns an empty ConstString because
/// it's assumed that the caller is using the DIE name anyway.
- lldb_private::ConstString
- GetDIEClassTemplateParams(const DWARFDIE &die) override;
+ lldb_private::ConstString GetDIEClassTemplateParams(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
protected:
/// Protected typedefs and members.
@@ -108,14 +114,19 @@ protected:
class DelayedAddObjCClassProperty;
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+ typedef llvm::DenseMap<
+ const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *,
+ clang::DeclContext *>
DIEToDeclContextMap;
- typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
+ typedef std::multimap<const clang::DeclContext *,
+ const lldb_private::plugin::dwarf::DWARFDIE>
DeclContextToDIEMap;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
- lldb_private::OptionalClangModuleID>
+ typedef llvm::DenseMap<
+ const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *,
+ lldb_private::OptionalClangModuleID>
DIEToModuleMap;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
+ typedef llvm::DenseMap<
+ const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *, clang::Decl *>
DIEToDeclMap;
lldb_private::TypeSystemClang &m_ast;
@@ -126,11 +137,14 @@ protected:
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
/// @}
- clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
+ clang::DeclContext *
+ GetDeclContextForBlock(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
+ clang::BlockDecl *
+ ResolveBlockDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
+ clang::NamespaceDecl *
+ ResolveNamespaceDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
/// Returns the namespace decl that a DW_TAG_imported_declaration imports.
///
@@ -141,82 +155,99 @@ protected:
/// 'die' imports. If the imported entity is not a namespace
/// or another import declaration, returns nullptr. If an error
/// occurs, returns nullptr.
- clang::NamespaceDecl *ResolveImportedDeclarationDIE(const DWARFDIE &die);
+ clang::NamespaceDecl *ResolveImportedDeclarationDIE(
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
- bool ParseTemplateDIE(const DWARFDIE &die,
+ bool ParseTemplateDIE(const lldb_private::plugin::dwarf::DWARFDIE &die,
lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
bool ParseTemplateParameterInfos(
- const DWARFDIE &parent_die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
- std::string GetCPlusPlusQualifiedName(const DWARFDIE &die);
+ std::string
+ GetCPlusPlusQualifiedName(const lldb_private::plugin::dwarf::DWARFDIE &die);
bool ParseChildMembers(
- const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::CompilerType &class_compiler_type,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
- std::vector<DWARFDIE> &member_function_dies,
+ std::vector<lldb_private::plugin::dwarf::DWARFDIE> &member_function_dies,
DelayedPropertyList &delayed_properties,
const lldb::AccessType default_accessibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
ParseChildParameters(clang::DeclContext *containing_decl_ctx,
- const DWARFDIE &parent_die, bool skip_artificial,
- bool &is_static, bool &is_variadic,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ bool skip_artificial, bool &is_static, bool &is_variadic,
bool &has_template_params,
std::vector<lldb_private::CompilerType> &function_args,
std::vector<clang::ParmVarDecl *> &function_param_decls,
unsigned &type_quals);
- size_t ParseChildEnumerators(lldb_private::CompilerType &compiler_type,
- bool is_signed, uint32_t enumerator_byte_size,
- const DWARFDIE &parent_die);
+ size_t ParseChildEnumerators(
+ lldb_private::CompilerType &compiler_type, bool is_signed,
+ uint32_t enumerator_byte_size,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die);
/// Parse a structure, class, or union type DIE.
- lldb::TypeSP ParseStructureLikeDIE(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
-
- lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
+ lldb::TypeSP
+ ParseStructureLikeDIE(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
- clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
+ clang::Decl *
+ GetClangDeclForDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die);
+ clang::DeclContext *
+ GetClangDeclContextForDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
- DWARFDIE *decl_ctx_die);
- lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die);
+ clang::DeclContext *GetClangDeclContextContainingDIE(
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::plugin::dwarf::DWARFDIE *decl_ctx_die);
+ lldb_private::OptionalClangModuleID
+ GetOwningClangModule(const lldb_private::plugin::dwarf::DWARFDIE &die);
- bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
- const DWARFDIE &dst_class_die,
- lldb_private::Type *class_type,
- std::vector<DWARFDIE> &failures);
+ bool CopyUniqueClassMethodTypes(
+ const lldb_private::plugin::dwarf::DWARFDIE &src_class_die,
+ const lldb_private::plugin::dwarf::DWARFDIE &dst_class_die,
+ lldb_private::Type *class_type,
+ std::vector<lldb_private::plugin::dwarf::DWARFDIE> &failures);
- clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
+ clang::DeclContext *GetCachedClangDeclContextForDIE(
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
- void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die);
+ void LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
- void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
+ void LinkDeclToDIE(clang::Decl *decl,
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
/// If \p type_sp is valid, calculate and set its symbol context scope, and
/// update the type list for its backing symbol file.
///
/// Returns \p type_sp.
- lldb::TypeSP
- UpdateSymbolContextScopeForType(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, lldb::TypeSP type_sp);
+ lldb::TypeSP UpdateSymbolContextScopeForType(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die, lldb::TypeSP type_sp);
/// Follow Clang Module Skeleton CU references to find a type definition.
- lldb::TypeSP ParseTypeFromClangModule(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- lldb_private::Log *log);
+ lldb::TypeSP
+ ParseTypeFromClangModule(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::Log *log);
// Return true if this type is a declaration to a type in an external
// module.
- lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
+ lldb::ModuleSP
+ GetModuleForType(const lldb_private::plugin::dwarf::DWARFDIE &die);
+
+ static bool classof(const DWARFASTParser *Parser) {
+ return Parser->GetKind() == Kind::DWARFASTParserClang;
+ }
private:
struct FieldInfo {
@@ -240,6 +271,30 @@ private:
}
};
+ /// Parsed form of all attributes that are relevant for parsing type members.
+ struct MemberAttributes {
+ explicit MemberAttributes(
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ lldb::ModuleSP module_sp);
+ const char *name = nullptr;
+ /// Indicates how many bits into the word (according to the host endianness)
+ /// the low-order bit of the field starts. Can be negative.
+ int64_t bit_offset = 0;
+ /// Indicates the size of the field in bits.
+ size_t bit_size = 0;
+ uint64_t data_bit_offset = UINT64_MAX;
+ lldb::AccessType accessibility = lldb::eAccessNone;
+ std::optional<uint64_t> byte_size;
+ std::optional<lldb_private::plugin::dwarf::DWARFFormValue> const_value_form;
+ lldb_private::plugin::dwarf::DWARFFormValue encoding_form;
+ /// Indicates the byte offset of the word from the base address of the
+ /// structure.
+ uint32_t member_byte_offset = UINT32_MAX;
+ bool is_artificial = false;
+ bool is_declaration = false;
+ };
+
/// Returns 'true' if we should create an unnamed bitfield
/// and add it to the parser's current AST.
///
@@ -268,33 +323,57 @@ private:
/// created property.
/// \param delayed_properties The list of delayed properties that the result
/// will be appended to.
- void ParseObjCProperty(const DWARFDIE &die, const DWARFDIE &parent_die,
- const lldb_private::CompilerType &class_clang_type,
- DelayedPropertyList &delayed_properties);
+ void
+ ParseObjCProperty(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ const lldb_private::CompilerType &class_clang_type,
+ DelayedPropertyList &delayed_properties);
void
- ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
+ ParseSingleMember(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
lldb::AccessType default_accessibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
FieldInfo &last_field_info);
- bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type,
+ /// If the specified 'die' represents a static data member, creates
+ /// a 'clang::VarDecl' for it and attaches it to specified parent
+ /// 'class_clang_type'.
+ ///
+ /// \param[in] die The member declaration we want to create a
+ /// clang::VarDecl for.
+ ///
+ /// \param[in] attrs The parsed attributes for the specified 'die'.
+ ///
+ /// \param[in] class_clang_type The parent RecordType of the static
+ /// member this function will create.
+ void CreateStaticMemberVariable(
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const MemberAttributes &attrs,
+ const lldb_private::CompilerType &class_clang_type);
+
+ bool CompleteRecordType(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
- bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type,
+ bool CompleteEnumType(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
- lldb::TypeSP ParseTypeModifier(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP
+ ParseTypeModifier(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParseEnum(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParseSubroutine(const DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParseArrayType(const DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP ParseSubroutine(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP ParseArrayType(const lldb_private::plugin::dwarf::DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
- const ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP
+ ParsePointerToMemberType(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const ParsedDWARFTypeAttributes &attrs);
/// Parses a DW_TAG_inheritance DIE into a base/super class.
///
@@ -311,19 +390,37 @@ private:
/// \param layout_info The layout information that will be updated for C++
/// base classes with the base offset.
void ParseInheritance(
- const DWARFDIE &die, const DWARFDIE &parent_die,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
const lldb_private::CompilerType class_clang_type,
const lldb::AccessType default_accessibility,
const lldb::ModuleSP &module_sp,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
+
+ /// Parses DW_TAG_variant_part DIE into a structure that encodes all variants
+ /// Note that this is currently being emitted by rustc and not Clang
+ /// \param die DW_TAG_variant_part DIE to parse
+ /// \param parent_die The parent DW_TAG_structure_type to parse
+ /// \param class_clang_type The Rust struct representing parent_die.
+ /// \param default_accesibility The default accessibility that is given to
+ /// base classes if they don't have an explicit accessibility set
+ /// \param layout_info The layout information that will be updated for
+ // base classes with the base offset
+ void
+ ParseRustVariantPart(lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ lldb_private::CompilerType &class_clang_type,
+ const lldb::AccessType default_accesibility,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info);
};
/// Parsed form of all attributes that are relevant for type reconstruction.
/// Some attributes are relevant for all kinds of types (declaration), while
/// others are only meaningful to a specific type (is_virtual)
struct ParsedDWARFTypeAttributes {
- explicit ParsedDWARFTypeAttributes(const DWARFDIE &die);
+ explicit ParsedDWARFTypeAttributes(
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
lldb::AccessType accessibility = lldb::eAccessNone;
bool is_artificial = false;
@@ -340,14 +437,15 @@ struct ParsedDWARFTypeAttributes {
const char *mangled_name = nullptr;
lldb_private::ConstString name;
lldb_private::Declaration decl;
- DWARFDIE object_pointer;
- DWARFFormValue abstract_origin;
- DWARFFormValue containing_type;
- DWARFFormValue signature;
- DWARFFormValue specification;
- DWARFFormValue type;
+ lldb_private::plugin::dwarf::DWARFDIE object_pointer;
+ lldb_private::plugin::dwarf::DWARFFormValue abstract_origin;
+ lldb_private::plugin::dwarf::DWARFFormValue containing_type;
+ lldb_private::plugin::dwarf::DWARFFormValue signature;
+ lldb_private::plugin::dwarf::DWARFFormValue specification;
+ lldb_private::plugin::dwarf::DWARFFormValue type;
lldb::LanguageType class_language = lldb::eLanguageTypeUnknown;
std::optional<uint64_t> byte_size;
+ std::optional<uint64_t> alignment;
size_t calling_convention = llvm::dwarf::DW_CC_normal;
uint32_t bit_stride = 0;
uint32_t byte_stride = 0;
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 00b56537ae2b..3d35775e081e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -11,6 +11,7 @@
#include "DWARFDebugInfo.h"
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
DWARFAttributes::DWARFAttributes() : m_infos() {}
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 90e12fa02493..e05ccc980d92 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -14,6 +14,8 @@
#include "llvm/ADT/SmallVector.h"
#include <vector>
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFUnit;
class DWARFAttribute {
@@ -31,6 +33,7 @@ public:
form = m_form;
val = m_value;
}
+
protected:
dw_attr_t m_attr;
dw_form_t m_form;
@@ -72,5 +75,7 @@ protected:
typedef llvm::SmallVector<AttributeValue, 8> collection;
collection m_infos;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 37a917c3a766..3a3b05acd26d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -18,6 +18,7 @@
#include <optional>
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
std::optional<DIERef> DWARFBaseDIE::GetDIERef() const {
if (!IsValid())
@@ -35,7 +36,7 @@ dw_tag_t DWARFBaseDIE::Tag() const {
}
const char *DWARFBaseDIE::GetTagAsCString() const {
- return lldb_private::DW_TAG_value_to_name(Tag());
+ return DW_TAG_value_to_name(Tag());
}
const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
@@ -120,6 +121,8 @@ DWARFAttributes DWARFBaseDIE::GetAttributes(Recurse recurse) const {
return DWARFAttributes();
}
+namespace lldb_private::plugin {
+namespace dwarf {
bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
}
@@ -127,6 +130,8 @@ bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
return !(lhs == rhs);
}
+} // namespace dwarf
+} // namespace lldb_private::plugin
const DWARFDataExtractor &DWARFBaseDIE::GetData() const {
// Clients must check if this DIE is valid before calling this function.
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 8bcf807ad163..75c822703cd8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -15,6 +15,8 @@
#include "llvm/Support/Error.h"
#include <optional>
+namespace lldb_private::plugin {
+namespace dwarf {
class DIERef;
class DWARFASTParser;
class DWARFAttributes;
@@ -78,7 +80,7 @@ public:
// correct section data.
//
// Clients must validate that this object is valid before calling this.
- const lldb_private::DWARFDataExtractor &GetData() const;
+ const DWARFDataExtractor &GetData() const;
// Accessing information about a DIE
dw_tag_t Tag() const;
@@ -124,5 +126,7 @@ protected:
bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index f839a59bf6c3..ec4c297cf7e1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -16,6 +16,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
void DWARFCompileUnit::Dump(Stream *s) const {
s->Format(
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index ab3017ba0ffc..dd130977d4b1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -12,11 +12,17 @@
#include "DWARFUnit.h"
#include "llvm/Support/Error.h"
+namespace llvm {
+class DWARFAbbreviationDeclarationSet;
+} // namespace llvm
+
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFCompileUnit : public DWARFUnit {
public:
void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) override;
- void Dump(lldb_private::Stream *s) const override;
+ void Dump(Stream *s) const override;
static bool classof(const DWARFUnit *unit) { return !unit->IsTypeUnit(); }
@@ -27,7 +33,7 @@ public:
private:
DWARFCompileUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
- const DWARFAbbreviationDeclarationSet &abbrevs,
+ const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo)
: DWARFUnit(dwarf, uid, header, abbrevs, section, is_dwo) {}
@@ -36,5 +42,7 @@ private:
friend class DWARFUnit;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
index f72dad88e157..e3872dc626be 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
@@ -13,6 +13,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
static DWARFDataExtractor LoadSection(SectionList *section_list,
SectionType section_type) {
@@ -141,7 +142,10 @@ llvm::DWARFContext &DWARFContext::GetAsLLVM() {
AddSection("debug_line_str", getOrLoadLineStrData());
AddSection("debug_cu_index", getOrLoadCuIndexData());
AddSection("debug_tu_index", getOrLoadTuIndexData());
-
+ if (isDwo()) {
+ AddSection("debug_info.dwo", getOrLoadDebugInfoData());
+ AddSection("debug_types.dwo", getOrLoadDebugTypesData());
+ }
m_llvm_context = llvm::DWARFContext::create(section_map, addr_size);
}
return *m_llvm_context;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
index 7df776b5f514..87c6eb209337 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
@@ -16,7 +16,8 @@
#include <memory>
#include <optional>
-namespace lldb_private {
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFContext {
private:
SectionList *m_main_section_list;
@@ -78,6 +79,7 @@ public:
llvm::DWARFContext &GetAsLLVM();
};
-} // namespace lldb_private
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif
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 b31c5dcac918..bed68f45426f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -18,6 +18,7 @@
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
namespace {
@@ -372,47 +373,97 @@ std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const {
return result;
}
-void DWARFDIE::GetDeclContext(
- llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const {
+std::vector<lldb_private::CompilerContext> DWARFDIE::GetDeclContext() const {
+ std::vector<lldb_private::CompilerContext> context;
const dw_tag_t tag = Tag();
if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
- return;
+ return context;
DWARFDIE parent = GetParent();
if (parent)
- parent.GetDeclContext(context);
+ context = parent.GetDeclContext();
+ auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) {
+ context.push_back({kind, ConstString(name)});
+ };
switch (tag) {
case DW_TAG_module:
- context.push_back({CompilerContextKind::Module, ConstString(GetName())});
+ push_ctx(CompilerContextKind::Module, GetName());
break;
case DW_TAG_namespace:
- context.push_back({CompilerContextKind::Namespace, ConstString(GetName())});
+ push_ctx(CompilerContextKind::Namespace, GetName());
break;
case DW_TAG_structure_type:
- context.push_back({CompilerContextKind::Struct, ConstString(GetName())});
+ push_ctx(CompilerContextKind::Struct, GetName());
break;
case DW_TAG_union_type:
- context.push_back({CompilerContextKind::Union, ConstString(GetName())});
+ push_ctx(CompilerContextKind::Union, GetName());
break;
case DW_TAG_class_type:
- context.push_back({CompilerContextKind::Class, ConstString(GetName())});
+ push_ctx(CompilerContextKind::Class, GetName());
break;
case DW_TAG_enumeration_type:
- context.push_back({CompilerContextKind::Enum, ConstString(GetName())});
+ push_ctx(CompilerContextKind::Enum, GetName());
break;
case DW_TAG_subprogram:
- context.push_back(
- {CompilerContextKind::Function, ConstString(GetPubname())});
+ push_ctx(CompilerContextKind::Function, GetPubname());
break;
case DW_TAG_variable:
- context.push_back(
- {CompilerContextKind::Variable, ConstString(GetPubname())});
+ push_ctx(CompilerContextKind::Variable, GetPubname());
break;
case DW_TAG_typedef:
- context.push_back({CompilerContextKind::Typedef, ConstString(GetName())});
+ push_ctx(CompilerContextKind::Typedef, GetName());
+ break;
+ default:
+ break;
+ }
+ return context;
+}
+
+std::vector<lldb_private::CompilerContext>
+DWARFDIE::GetTypeLookupContext() const {
+ std::vector<lldb_private::CompilerContext> context;
+ // If there is no name, then there is no need to look anything up for this
+ // DIE.
+ const char *name = GetName();
+ if (!name || !name[0])
+ return context;
+ const dw_tag_t tag = Tag();
+ if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
+ return context;
+ DWARFDIE parent = GetParent();
+ if (parent)
+ context = parent.GetTypeLookupContext();
+ auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) {
+ context.push_back({kind, ConstString(name)});
+ };
+ switch (tag) {
+ case DW_TAG_namespace:
+ push_ctx(CompilerContextKind::Namespace, name);
+ break;
+ case DW_TAG_structure_type:
+ push_ctx(CompilerContextKind::Struct, name);
+ break;
+ case DW_TAG_union_type:
+ push_ctx(CompilerContextKind::Union, name);
+ break;
+ case DW_TAG_class_type:
+ push_ctx(CompilerContextKind::Class, name);
+ break;
+ case DW_TAG_enumeration_type:
+ push_ctx(CompilerContextKind::Enum, name);
+ break;
+ case DW_TAG_variable:
+ push_ctx(CompilerContextKind::Variable, GetPubname());
+ break;
+ case DW_TAG_typedef:
+ push_ctx(CompilerContextKind::Typedef, name);
+ break;
+ case DW_TAG_base_type:
+ push_ctx(CompilerContextKind::Builtin, name);
break;
default:
break;
}
+ return context;
}
DWARFDIE
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 031ea26ad405..511ca62d0197 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -13,6 +13,8 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/iterator_range.h"
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFDIE : public DWARFBaseDIE {
public:
class child_iterator;
@@ -31,14 +33,14 @@ public:
const char *GetPubname() const;
using DWARFBaseDIE::GetName;
- void GetName(lldb_private::Stream &s) const;
+ void GetName(Stream &s) const;
- void AppendTypeName(lldb_private::Stream &s) const;
+ void AppendTypeName(Stream &s) const;
- lldb_private::Type *ResolveType() const;
+ Type *ResolveType() const;
// Resolve a type by UID using this DIE's DWARF file
- lldb_private::Type *ResolveTypeUID(const DWARFDIE &die) const;
+ Type *ResolveTypeUID(const DWARFDIE &die) const;
// Functions for obtaining DIE relations and references
@@ -71,9 +73,21 @@ public:
std::vector<DWARFDIE> GetDeclContextDIEs() const;
/// Return this DIE's decl context as it is needed to look up types
- /// in Clang's -gmodules debug info format.
- void GetDeclContext(
- llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const;
+ /// in Clang modules. This context will include any modules or functions that
+ /// the type is declared in so an exact module match can be efficiently made.
+ std::vector<CompilerContext> GetDeclContext() const;
+
+ /// Get a context to a type so it can be looked up.
+ ///
+ /// This function uses the current DIE to fill in a CompilerContext array
+ /// that is suitable for type lookup for comparison to a TypeQuery's compiler
+ /// context (TypeQuery::GetContextRef()). If this DIE represents a named type,
+ /// it should fill out the compiler context with the type itself as the last
+ /// entry. The declaration context should be above the type and stop at an
+ /// appropriate time, like either the translation unit or at a function
+ /// context. This is designed to allow users to efficiently look for types
+ /// using a full or partial CompilerContext array.
+ std::vector<CompilerContext> GetTypeLookupContext() const;
// Getting attribute values from the DIE.
//
@@ -88,7 +102,7 @@ public:
std::optional<int> &decl_file, std::optional<int> &decl_line,
std::optional<int> &decl_column, std::optional<int> &call_file,
std::optional<int> &call_line, std::optional<int> &call_column,
- lldb_private::DWARFExpressionList *frame_base) const;
+ DWARFExpressionList *frame_base) const;
/// The range of all the children of this DIE.
llvm::iterator_range<child_iterator> children() const;
@@ -126,5 +140,7 @@ public:
return *this;
}
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
index b9526b079c1e..41b8e9ad0217 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -33,6 +33,6 @@ public:
llvm::DWARFDataExtractor GetAsLLVMDWARF() const;
llvm::DataExtractor GetAsLLVM() const;
};
-}
+} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
deleted file mode 100644
index 0cd53463ee65..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- DWARFDebugAbbrev.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 "DWARFDebugAbbrev.h"
-#include "DWARFDataExtractor.h"
-#include "DWARFFormValue.h"
-#include "lldb/Utility/Stream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// DWARFDebugAbbrev constructor
-DWARFDebugAbbrev::DWARFDebugAbbrev()
- : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
-
-// DWARFDebugAbbrev::Parse()
-llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) {
- llvm::DataExtractor llvm_data = data.GetAsLLVM();
- lldb::offset_t offset = 0;
-
- while (llvm_data.isValidOffset(offset)) {
- uint32_t initial_cu_offset = offset;
- DWARFAbbreviationDeclarationSet abbrevDeclSet;
-
- llvm::Error error = abbrevDeclSet.extract(llvm_data, &offset);
- if (error)
- return error;
-
- m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
- }
- m_prev_abbr_offset_pos = m_abbrevCollMap.end();
- return llvm::ErrorSuccess();
-}
-
-// DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
-const DWARFAbbreviationDeclarationSet *
-DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
- dw_offset_t cu_abbr_offset) const {
- DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
- DWARFAbbreviationDeclarationCollMapConstIter pos;
- if (m_prev_abbr_offset_pos != end &&
- m_prev_abbr_offset_pos->first == cu_abbr_offset)
- return &(m_prev_abbr_offset_pos->second);
- else {
- pos = m_abbrevCollMap.find(cu_abbr_offset);
- m_prev_abbr_offset_pos = pos;
- }
-
- if (pos != m_abbrevCollMap.end())
- return &(pos->second);
- return nullptr;
-}
-
-// DWARFDebugAbbrev::GetUnsupportedForms()
-void DWARFDebugAbbrev::GetUnsupportedForms(
- std::set<dw_form_t> &invalid_forms) const {
- for (const auto &pair : m_abbrevCollMap)
- for (const auto &decl : pair.second)
- for (const auto &attr : decl.attributes())
- if (!DWARFFormValue::FormIsSupported(attr.Form))
- invalid_forms.insert(attr.Form);
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
deleted file mode 100644
index 0a579e34b001..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- DWARFDebugAbbrev.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_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H
-#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H
-
-#include "DWARFDefines.h"
-#include "lldb/lldb-private.h"
-
-#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-
-#include <map>
-
-using DWARFAbbreviationDeclaration = llvm::DWARFAbbreviationDeclaration;
-using DWARFAbbreviationDeclarationSet = llvm::DWARFAbbreviationDeclarationSet;
-
-typedef std::map<dw_offset_t, DWARFAbbreviationDeclarationSet>
- DWARFAbbreviationDeclarationCollMap;
-typedef DWARFAbbreviationDeclarationCollMap::iterator
- DWARFAbbreviationDeclarationCollMapIter;
-typedef DWARFAbbreviationDeclarationCollMap::const_iterator
- DWARFAbbreviationDeclarationCollMapConstIter;
-
-class DWARFDebugAbbrev {
-public:
- DWARFDebugAbbrev();
- const DWARFAbbreviationDeclarationSet *
- GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
- /// Extract all abbreviations for a particular compile unit. Returns
- /// llvm::ErrorSuccess() on success, and an appropriate llvm::Error object
- /// otherwise.
- llvm::Error parse(const lldb_private::DWARFDataExtractor &data);
- void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
-
-protected:
- DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;
- mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos;
-};
-
-#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H
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 03cbfd28ae74..8461b94abca6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -13,6 +13,7 @@
#include <cassert>
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
DWARFDebugArangeSet::DWARFDebugArangeSet()
: m_offset(DW_INVALID_OFFSET), m_next_offset(DW_INVALID_OFFSET) {}
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 3c8633eaa3cc..ecdbe953f58b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -13,6 +13,8 @@
#include <cstdint>
#include <vector>
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFDebugArangeSet {
public:
struct Header {
@@ -42,7 +44,7 @@ public:
DWARFDebugArangeSet();
void Clear();
void SetOffset(uint32_t offset) { m_offset = offset; }
- llvm::Error extract(const lldb_private::DWARFDataExtractor &data,
+ llvm::Error extract(const DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
dw_offset_t FindAddress(dw_addr_t address) const;
size_t NumDescriptors() const { return m_arange_descriptors.size(); }
@@ -62,5 +64,7 @@ protected:
Header m_header;
DescriptorColl m_arange_descriptors;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H
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 b38dd2b88c9d..da73891f6665 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -15,6 +15,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
// Constructor
DWARFDebugAranges::DWARFDebugAranges() : m_aranges() {}
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 5ff37e400c88..99e2108b85c6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -13,10 +13,11 @@
#include "lldb/Utility/RangeMap.h"
#include "llvm/Support/Error.h"
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFDebugAranges {
protected:
- typedef lldb_private::RangeDataVector<dw_addr_t, uint32_t, dw_offset_t>
- RangeToDIE;
+ typedef RangeDataVector<dw_addr_t, uint32_t, dw_offset_t> RangeToDIE;
public:
typedef RangeToDIE::Entry Range;
@@ -26,14 +27,14 @@ public:
void Clear() { m_aranges.Clear(); }
- void extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
+ void extract(const 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);
void Sort(bool minimize);
- void Dump(lldb_private::Log *log) const;
+ void Dump(Log *log) const;
dw_offset_t FindAddress(dw_addr_t address) const;
@@ -50,5 +51,7 @@ public:
protected:
RangeToDIE m_aranges;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H
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 9a33d6338b87..553b6a4c551d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -27,10 +27,10 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
// Constructor
-DWARFDebugInfo::DWARFDebugInfo(SymbolFileDWARF &dwarf,
- lldb_private::DWARFContext &context)
+DWARFDebugInfo::DWARFDebugInfo(SymbolFileDWARF &dwarf, DWARFContext &context)
: m_dwarf(dwarf), m_context(context), m_units(), m_cu_aranges_up() {}
const DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() {
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 c990ac9fbe58..d5e48f312ea0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -19,20 +19,18 @@
#include "lldb/lldb-private.h"
#include "llvm/Support/Error.h"
-namespace lldb_private {
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFContext;
-}
class DWARFDebugInfo {
public:
- typedef dw_offset_t (*Callback)(SymbolFileDWARF *dwarf2Data,
- DWARFUnit *cu,
+ typedef dw_offset_t (*Callback)(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
DWARFDebugInfoEntry *die,
const dw_offset_t next_offset,
const uint32_t depth, void *userData);
- explicit DWARFDebugInfo(SymbolFileDWARF &dwarf,
- lldb_private::DWARFContext &context);
+ explicit DWARFDebugInfo(SymbolFileDWARF &dwarf, DWARFContext &context);
size_t GetNumUnits();
DWARFUnit *GetUnitAtIndex(size_t idx);
@@ -58,7 +56,7 @@ protected:
typedef std::vector<DWARFUnitSP> UnitColl;
SymbolFileDWARF &m_dwarf;
- lldb_private::DWARFContext &m_context;
+ DWARFContext &m_context;
llvm::once_flag m_units_once_flag;
UnitColl m_units;
@@ -80,5 +78,7 @@ private:
DWARFDebugInfo(const DWARFDebugInfo &) = delete;
const DWARFDebugInfo &operator=(const DWARFDebugInfo &) = delete;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H
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 a08637aef066..1b0fefedf983 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -22,7 +22,6 @@
#include "lldb/Utility/StreamString.h"
#include "DWARFCompileUnit.h"
-#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugRanges.h"
@@ -32,8 +31,11 @@
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDwo.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
extern int g_verbose;
// Extract a debug info entry for a given DWARFUnit from the data
@@ -48,16 +50,12 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
lldbassert(abbr_idx <= UINT16_MAX);
m_abbr_idx = abbr_idx;
- // assert (fixed_form_sizes); // For best performance this should be
- // specified!
-
if (m_abbr_idx == 0) {
m_tag = llvm::dwarf::DW_TAG_null;
m_has_children = false;
return true; // NULL debug tag entry
}
- lldb::offset_t offset = *offset_ptr;
const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
if (abbrevDecl == nullptr) {
cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
@@ -72,137 +70,18 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
m_tag = abbrevDecl->getTag();
m_has_children = abbrevDecl->hasChildren();
// Skip all data in the .debug_info or .debug_types for the attributes
- dw_form_t form;
for (const auto &attribute : abbrevDecl->attributes()) {
- form = attribute.Form;
- std::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;
+ if (DWARFFormValue::SkipValue(attribute.Form, data, offset_ptr, cu))
+ continue;
- // 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 = static_cast<dw_form_t>(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(
- "[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug "
- "and "
- "attach the file at the start of this error message",
- (uint64_t)m_offset, (unsigned)form);
- *offset_ptr = m_offset;
- return false;
- }
- offset += form_size;
-
- } while (form_is_indirect);
- }
+ cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug "
+ "and "
+ "attach the file at the start of this error message",
+ (uint64_t)m_offset, (unsigned)attribute.Form);
+ *offset_ptr = m_offset;
+ return false;
}
- *offset_ptr = offset;
return true;
}
@@ -810,12 +689,13 @@ lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
}
-const DWARFAbbreviationDeclaration *
+const llvm::DWARFAbbreviationDeclaration *
DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
if (!cu)
return nullptr;
- const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
+ const llvm::DWARFAbbreviationDeclarationSet *abbrev_set =
+ cu->GetAbbreviations();
if (!abbrev_set)
return nullptr;
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 c2ea40065232..c19fa7428549 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -14,7 +14,6 @@
#include "DWARFAttribute.h"
#include "DWARFBaseDIE.h"
-#include "DWARFDebugAbbrev.h"
#include "DWARFDebugRanges.h"
#include <map>
#include <optional>
@@ -23,6 +22,8 @@
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFDeclContext;
#define DIE_SIBLING_IDX_BITSIZE 31
@@ -48,8 +49,8 @@ public:
void BuildFunctionAddressRangeTable(DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const;
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- const DWARFUnit *cu, lldb::offset_t *offset_ptr);
+ bool Extract(const DWARFDataExtractor &data, const DWARFUnit *cu,
+ lldb::offset_t *offset_ptr);
using Recurse = DWARFBaseDIE::Recurse;
DWARFAttributes GetAttributes(DWARFUnit *cu,
@@ -105,13 +106,15 @@ public:
const char *GetPubname(const DWARFUnit *cu) const;
- bool GetDIENamesAndRanges(
- DWARFUnit *cu, const char *&name, const char *&mangled,
- DWARFRangeList &rangeList, std::optional<int> &decl_file,
- std::optional<int> &decl_line, std::optional<int> &decl_column,
- std::optional<int> &call_file, std::optional<int> &call_line,
- std::optional<int> &call_column,
- lldb_private::DWARFExpressionList *frame_base = nullptr) const;
+ bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name,
+ const char *&mangled, DWARFRangeList &rangeList,
+ std::optional<int> &decl_file,
+ std::optional<int> &decl_line,
+ std::optional<int> &decl_column,
+ std::optional<int> &call_file,
+ std::optional<int> &call_line,
+ std::optional<int> &call_column,
+ DWARFExpressionList *frame_base = nullptr) const;
const llvm::DWARFAbbreviationDeclaration *
GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;
@@ -191,5 +194,7 @@ private:
void GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse,
uint32_t curr_depth) const;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
index 19c6448c4e74..2cd84bc55b75 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
@@ -15,6 +15,7 @@
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
DWARFDebugMacroHeader
DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
index cbf762458331..67d1cde8d5de 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
@@ -17,11 +17,11 @@
#include "lldb/lldb-types.h"
namespace lldb_private {
-
class DWARFDataExtractor;
+}
-} // namespace lldb_private
-
+namespace lldb_private::plugin {
+namespace dwarf {
class SymbolFileDWARF;
class DWARFDebugMacroHeader {
@@ -33,15 +33,14 @@ public:
};
static DWARFDebugMacroHeader
- ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data,
+ ParseHeader(const DWARFDataExtractor &debug_macro_data,
lldb::offset_t *offset);
bool OffsetIs64Bit() const { return m_offset_is_64_bit; }
private:
- static void
- SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data,
- lldb::offset_t *offset);
+ static void SkipOperandTable(const DWARFDataExtractor &debug_macro_data,
+ lldb::offset_t *offset);
uint16_t m_version = 0;
bool m_offset_is_64_bit = false;
@@ -50,12 +49,14 @@ private:
class DWARFDebugMacroEntry {
public:
- static void
- ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data,
- const lldb_private::DWARFDataExtractor &debug_str_data,
- const bool offset_is_64_bit, lldb::offset_t *sect_offset,
- SymbolFileDWARF *sym_file_dwarf,
- lldb_private::DebugMacrosSP &debug_macros_sp);
+ static void ReadMacroEntries(const DWARFDataExtractor &debug_macro_data,
+ const DWARFDataExtractor &debug_str_data,
+ const bool offset_is_64_bit,
+ lldb::offset_t *sect_offset,
+ SymbolFileDWARF *sym_file_dwarf,
+ DebugMacrosSP &debug_macros_sp);
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 0b5bb23a4981..fd8f4e12ff77 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -11,6 +11,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index 2e06cd5daf6f..a04fcf59d5bf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -12,21 +12,23 @@
#include "lldb/Core/dwarf.h"
#include <map>
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFUnit;
-namespace lldb_private {
class DWARFContext;
-}
class DWARFDebugRanges {
public:
DWARFDebugRanges();
- void Extract(lldb_private::DWARFContext &context);
+ void Extract(DWARFContext &context);
DWARFRangeList FindRanges(const DWARFUnit *cu,
dw_offset_t debug_ranges_offset) const;
protected:
std::map<dw_offset_t, DWARFRangeList> m_range_map;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
index 393de0038e65..44421c0eda3e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
@@ -7,8 +7,26 @@
//===----------------------------------------------------------------------===//
#include "DWARFDeclContext.h"
+#include "llvm/Support/raw_ostream.h"
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
+
+/// Returns the name of `entry` if it has one, or the appropriate "anonymous
+/// {namespace, class, struct, union}".
+static const char *GetName(DWARFDeclContext::Entry entry) {
+ if (entry.name != nullptr)
+ return entry.name;
+ if (entry.tag == DW_TAG_namespace)
+ return "(anonymous namespace)";
+ if (entry.tag == DW_TAG_class_type)
+ return "(anonymous class)";
+ if (entry.tag == DW_TAG_structure_type)
+ return "(anonymous struct)";
+ if (entry.tag == DW_TAG_union_type)
+ return "(anonymous union)";
+ return "(anonymous)";
+}
const char *DWARFDeclContext::GetQualifiedName() const {
if (m_qualified_name.empty()) {
@@ -25,26 +43,10 @@ const char *DWARFDeclContext::GetQualifiedName() const {
m_qualified_name.append(m_entries[0].name);
}
} else {
- collection::const_reverse_iterator pos;
- collection::const_reverse_iterator begin = m_entries.rbegin();
- collection::const_reverse_iterator end = m_entries.rend();
- for (pos = begin; pos != end; ++pos) {
- if (pos != begin)
- m_qualified_name.append("::");
- if (pos->name == nullptr) {
- if (pos->tag == DW_TAG_namespace)
- m_qualified_name.append("(anonymous namespace)");
- else if (pos->tag == DW_TAG_class_type)
- m_qualified_name.append("(anonymous class)");
- else if (pos->tag == DW_TAG_structure_type)
- m_qualified_name.append("(anonymous struct)");
- else if (pos->tag == DW_TAG_union_type)
- m_qualified_name.append("(anonymous union)");
- else
- m_qualified_name.append("(anonymous)");
- } else
- m_qualified_name.append(pos->name);
- }
+ llvm::raw_string_ostream string_stream(m_qualified_name);
+ llvm::interleave(
+ llvm::reverse(m_entries), string_stream,
+ [&](auto entry) { string_stream << GetName(entry); }, "::");
}
}
}
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 13e3dfb70c0c..a20a862d3402 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -16,6 +16,8 @@
#include <string>
#include <vector>
+namespace lldb_private::plugin {
+namespace dwarf {
// DWARFDeclContext
//
// A class that represents a declaration context all the way down to a
@@ -68,8 +70,8 @@ public:
// Same as GetQualifiedName, but the life time of the returned string will
// be that of the LLDB session.
- lldb_private::ConstString GetQualifiedNameAsConstString() const {
- return lldb_private::ConstString(GetQualifiedName());
+ ConstString GetQualifiedNameAsConstString() const {
+ return ConstString(GetQualifiedName());
}
void Clear() {
@@ -82,5 +84,7 @@ protected:
collection m_entries;
mutable std::string m_qualified_name;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 4e99a295ce50..9a88aed85e97 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -12,7 +12,8 @@
#include <cstring>
#include <string>
-namespace lldb_private {
+namespace lldb_private::plugin {
+namespace dwarf {
const char *DW_TAG_value_to_name(uint32_t val) {
static char invalid[100];
@@ -88,4 +89,5 @@ const char *DW_LNS_value_to_name(uint32_t val) {
return llvmstr.data();
}
-} // namespace lldb_private
+} // namespace dwarf
+} // namespace lldb_private::plugin
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 2afdbb47381a..3ed92cc203bf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -12,7 +12,8 @@
#include "lldb/Core/dwarf.h"
#include <cstdint>
-namespace lldb_private {
+namespace lldb_private::plugin {
+namespace dwarf {
typedef uint32_t DRC_class; // Holds DRC_* class bitfields
@@ -30,6 +31,7 @@ const char *DW_LANG_value_to_name(uint32_t val);
const char *DW_LNS_value_to_name(uint32_t val);
-} // namespace lldb_private
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H
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 6ca17dcf47ff..0a7029a55c04 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -22,6 +22,7 @@ class DWARFUnit;
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
void DWARFFormValue::Clear() {
m_unit = nullptr;
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 2a8843c1a0d4..445749a6aac3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -13,6 +13,8 @@
#include <cstddef>
#include <optional>
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFUnit;
class SymbolFileDWARF;
class DWARFDIE;
@@ -51,9 +53,8 @@ public:
ValueType &ValueRef() { return m_value; }
void SetValue(const ValueType &val) { m_value = val; }
- void Dump(lldb_private::Stream &s) const;
- bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr);
+ void Dump(Stream &s) const;
+ bool ExtractValue(const DWARFDataExtractor &data, lldb::offset_t *offset_ptr);
const uint8_t *BlockData() const;
static std::optional<uint8_t> GetFixedSize(dw_form_t form,
const DWARFUnit *u);
@@ -68,10 +69,10 @@ public:
const char *AsCString() const;
dw_addr_t Address() const;
bool IsValid() const { return m_form != 0; }
- bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data,
+ bool SkipValue(const DWARFDataExtractor &debug_info_data,
lldb::offset_t *offset_ptr) const;
static bool SkipValue(const dw_form_t form,
- const lldb_private::DWARFDataExtractor &debug_info_data,
+ const DWARFDataExtractor &debug_info_data,
lldb::offset_t *offset_ptr, const DWARFUnit *unit);
static bool IsBlockForm(const dw_form_t form);
static bool IsDataForm(const dw_form_t form);
@@ -84,7 +85,9 @@ protected:
// It may be different from compile unit where m_value refers to.
const DWARFUnit *m_unit = nullptr; // Unit for this form
dw_form_t m_form = dw_form_t(0); // Form for this value
- ValueType m_value; // Contains all data for the form
+ ValueType m_value; // Contains all data for the form
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
index 779b52481b85..b1c323b101ce 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -17,6 +17,7 @@
using namespace lldb_private;
using namespace lldb;
+using namespace lldb_private::plugin::dwarf;
DWARFIndex::~DWARFIndex() = default;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
index 13fe96dae2aa..9aadeddbb217 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -17,10 +17,11 @@
#include "lldb/Core/Module.h"
#include "lldb/Target/Statistics.h"
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFDeclContext;
class DWARFDIE;
-namespace lldb_private {
class DWARFIndex {
public:
DWARFIndex(Module &module) : m_module(module) {}
@@ -102,6 +103,7 @@ protected:
void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const;
};
-} // namespace lldb_private
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
index 87af7177ca95..4f3a3f544653 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
@@ -13,6 +13,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
void DWARFTypeUnit::Dump(Stream *s) const {
s->Format("{0:x16}: Type Unit: length = {1:x8}, version = {2:x4}, "
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
index 5e4d48ab285a..7b58c632c6c5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -12,11 +12,17 @@
#include "DWARFUnit.h"
#include "llvm/Support/Error.h"
+namespace llvm {
+class DWARFAbbreviationDeclarationSet;
+} // namespace llvm
+
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFTypeUnit : public DWARFUnit {
public:
void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) override {}
- void Dump(lldb_private::Stream *s) const override;
+ void Dump(Stream *s) const override;
uint64_t GetTypeHash() { return m_header.GetTypeHash(); }
@@ -27,11 +33,13 @@ public:
private:
DWARFTypeUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
- const DWARFAbbreviationDeclarationSet &abbrevs,
+ const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo)
: DWARFUnit(dwarf, uid, header, abbrevs, section, is_dwo) {}
friend class DWARFUnit;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H
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 749ffcb094ec..0e2f4d45543b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -13,6 +13,7 @@
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/Object/Error.h"
@@ -27,12 +28,13 @@
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
extern int g_verbose;
DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
- const DWARFAbbreviationDeclarationSet &abbrevs,
+ const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo)
: UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs),
m_cancel_scopes(false), m_section(section), m_is_dwo(is_dwo),
@@ -200,8 +202,8 @@ DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(ScopedExtractDIEs &&rhs)
rhs.m_cu = nullptr;
}
-DWARFUnit::ScopedExtractDIEs &DWARFUnit::ScopedExtractDIEs::operator=(
- DWARFUnit::ScopedExtractDIEs &&rhs) {
+DWARFUnit::ScopedExtractDIEs &
+DWARFUnit::ScopedExtractDIEs::operator=(DWARFUnit::ScopedExtractDIEs &&rhs) {
m_cu = rhs.m_cu;
rhs.m_cu = nullptr;
m_clear_dies = rhs.m_clear_dies;
@@ -310,9 +312,9 @@ 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.
+ // 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) {
@@ -435,7 +437,8 @@ size_t DWARFUnit::GetDebugInfoSize() const {
return GetLengthByteSize() + GetLength() - GetHeaderByteSize();
}
-const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const {
+const llvm::DWARFAbbreviationDeclarationSet *
+DWARFUnit::GetAbbreviations() const {
return m_abbrevs;
}
@@ -718,7 +721,7 @@ void DWARFUnit::ParseProducerInfo() {
llvm::SmallVector<llvm::StringRef, 3> matches;
if (g_swiftlang_version_regex.Execute(producer, &matches)) {
- m_producer_version.tryParse(matches[1]);
+ m_producer_version.tryParse(matches[1]);
m_producer = eProducerSwift;
} else if (producer.contains("clang")) {
if (g_clang_version_regex.Execute(producer, &matches))
@@ -806,7 +809,7 @@ removeHostnameFromPathname(llvm::StringRef path_from_dwarf) {
// check whether we have a windows path, and so the first character is a
// drive-letter not a hostname.
if (host.size() == 1 && llvm::isAlpha(host[0]) &&
- (path.startswith("\\") || path.startswith("/")))
+ (path.starts_with("\\") || path.starts_with("/")))
return path_from_dwarf;
return path;
@@ -875,10 +878,37 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
return *m_func_aranges_up;
}
+llvm::Error DWARFUnitHeader::ApplyIndexEntry(
+ const llvm::DWARFUnitIndex::Entry *index_entry) {
+ // We should only be calling this function when the index entry is not set and
+ // we have a valid one to set it to.
+ assert(index_entry);
+ assert(!m_index_entry);
+
+ if (m_abbr_offset)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Package unit with a non-zero abbreviation offset");
+
+ auto *unit_contrib = index_entry->getContribution();
+ if (!unit_contrib || unit_contrib->getLength32() != m_length + 4)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Inconsistent DWARF package unit index");
+
+ auto *abbr_entry = index_entry->getContribution(llvm::DW_SECT_ABBREV);
+ if (!abbr_entry)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "DWARF package index missing abbreviation column");
+
+ m_abbr_offset = abbr_entry->getOffset();
+ m_index_entry = index_entry;
+ return llvm::Error::success();
+}
+
llvm::Expected<DWARFUnitHeader>
DWARFUnitHeader::extract(const DWARFDataExtractor &data,
- DIERef::Section section,
- lldb_private::DWARFContext &context,
+ DIERef::Section section, DWARFContext &context,
lldb::offset_t *offset_ptr) {
DWARFUnitHeader header;
header.m_offset = *offset_ptr;
@@ -903,42 +933,6 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
header.m_type_offset = data.GetDWARFOffset(offset_ptr);
}
- if (context.isDwo()) {
- const llvm::DWARFUnitIndex *Index;
- if (header.IsTypeUnit()) {
- Index = &context.GetAsLLVM().getTUIndex();
- if (*Index)
- header.m_index_entry = Index->getFromHash(header.m_type_hash);
- } else {
- Index = &context.GetAsLLVM().getCUIndex();
- if (*Index && header.m_version >= 5 && header.m_dwo_id)
- header.m_index_entry = Index->getFromHash(*header.m_dwo_id);
- }
- if (!header.m_index_entry)
- header.m_index_entry = Index->getFromOffset(header.m_offset);
- }
-
- if (header.m_index_entry) {
- if (header.m_abbr_offset) {
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(),
- "Package unit with a non-zero abbreviation offset");
- }
- auto *unit_contrib = header.m_index_entry->getContribution();
- if (!unit_contrib || unit_contrib->getLength32() != header.m_length + 4) {
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Inconsistent DWARF package unit index");
- }
- auto *abbr_entry =
- header.m_index_entry->getContribution(llvm::DW_SECT_ABBREV);
- if (!abbr_entry) {
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(),
- "DWARF package index missing abbreviation column");
- }
- header.m_abbr_offset = abbr_entry->getOffset();
- }
-
bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version);
bool addr_size_OK = (header.m_addr_size == 2) || (header.m_addr_size == 4) ||
@@ -968,12 +962,31 @@ DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
DIERef::Section section, lldb::offset_t *offset_ptr) {
assert(debug_info.ValidOffset(*offset_ptr));
- auto expected_header = DWARFUnitHeader::extract(
- debug_info, section, dwarf.GetDWARFContext(), offset_ptr);
+ DWARFContext &context = dwarf.GetDWARFContext();
+ auto expected_header =
+ DWARFUnitHeader::extract(debug_info, section, context, offset_ptr);
if (!expected_header)
return expected_header.takeError();
- const DWARFDebugAbbrev *abbr = dwarf.DebugAbbrev();
+ if (context.isDwo()) {
+ const llvm::DWARFUnitIndex::Entry *entry = nullptr;
+ const llvm::DWARFUnitIndex &index = expected_header->IsTypeUnit()
+ ? context.GetAsLLVM().getTUIndex()
+ : context.GetAsLLVM().getCUIndex();
+ if (index) {
+ if (expected_header->IsTypeUnit())
+ entry = index.getFromHash(expected_header->GetTypeHash());
+ else if (auto dwo_id = expected_header->GetDWOId())
+ entry = index.getFromHash(*dwo_id);
+ }
+ if (!entry)
+ entry = index.getFromOffset(expected_header->GetOffset());
+ if (entry)
+ if (llvm::Error err = expected_header->ApplyIndexEntry(entry))
+ return std::move(err);
+ }
+
+ const llvm::DWARFDebugAbbrev *abbr = dwarf.DebugAbbrev();
if (!abbr)
return llvm::make_error<llvm::object::GenericBinaryError>(
"No debug_abbrev data");
@@ -985,8 +998,12 @@ DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
return llvm::make_error<llvm::object::GenericBinaryError>(
"Abbreviation offset for unit is not valid");
- const DWARFAbbreviationDeclarationSet *abbrevs =
- abbr->GetAbbreviationDeclarationSet(expected_header->GetAbbrOffset());
+ llvm::Expected<const llvm::DWARFAbbreviationDeclarationSet *> abbrevs_or_err =
+ abbr->getAbbreviationDeclarationSet(expected_header->GetAbbrOffset());
+ if (!abbrevs_or_err)
+ return abbrevs_or_err.takeError();
+
+ const llvm::DWARFAbbreviationDeclarationSet *abbrevs = *abbrevs_or_err;
if (!abbrevs)
return llvm::make_error<llvm::object::GenericBinaryError>(
"No abbrev exists at the specified offset.");
@@ -1071,22 +1088,20 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
return ranges;
}
-llvm::Expected<DWARFRangeList>
-DWARFUnit::FindRnglistFromIndex(uint32_t index) {
+llvm::Expected<DWARFRangeList> DWARFUnit::FindRnglistFromIndex(uint32_t index) {
llvm::Expected<uint64_t> maybe_offset = GetRnglistOffset(index);
if (!maybe_offset)
return maybe_offset.takeError();
return FindRnglistFromOffset(*maybe_offset);
}
-
bool DWARFUnit::HasAny(llvm::ArrayRef<dw_tag_t> tags) {
ExtractUnitDIEIfNeeded();
if (m_dwo)
return m_dwo->HasAny(tags);
- for (const auto &die: m_die_array) {
- for (const auto tag: tags) {
+ for (const auto &die : m_die_array) {
+ for (const auto tag : tags) {
if (tag == die.Tag())
return true;
}
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 bc55b093e894..3f528e913d8c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -13,11 +13,14 @@
#include "DWARFDebugInfoEntry.h"
#include "lldb/Utility/XcodeSDK.h"
#include "lldb/lldb-enumerations.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/Support/RWMutex.h"
#include <atomic>
#include <optional>
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFUnit;
class DWARFCompileUnit;
class NameToDIE;
@@ -73,23 +76,25 @@ public:
return m_unit_type == llvm::dwarf::DW_UT_type ||
m_unit_type == llvm::dwarf::DW_UT_split_type;
}
- uint32_t GetNextUnitOffset() const { return m_offset + m_length + 4; }
+ dw_offset_t GetNextUnitOffset() const { return m_offset + m_length + 4; }
- static llvm::Expected<DWARFUnitHeader>
- extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section,
- lldb_private::DWARFContext &dwarf_context,
- lldb::offset_t *offset_ptr);
+ llvm::Error ApplyIndexEntry(const llvm::DWARFUnitIndex::Entry *index_entry);
+
+ static llvm::Expected<DWARFUnitHeader> extract(const DWARFDataExtractor &data,
+ DIERef::Section section,
+ DWARFContext &dwarf_context,
+ lldb::offset_t *offset_ptr);
};
-class DWARFUnit : public lldb_private::UserID {
+class DWARFUnit : public UserID {
using die_iterator_range =
llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
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 DWARFDataExtractor &debug_info, DIERef::Section section,
+ lldb::offset_t *offset_ptr);
virtual ~DWARFUnit();
bool IsDWOUnit() { return m_is_dwo; }
@@ -101,6 +106,7 @@ public:
class ScopedExtractDIEs {
DWARFUnit *m_cu;
+
public:
bool m_clear_dies = false;
ScopedExtractDIEs(DWARFUnit &cu);
@@ -112,8 +118,8 @@ public:
};
ScopedExtractDIEs ExtractDIEsScoped();
- bool Verify(lldb_private::Stream *s) const;
- virtual void Dump(lldb_private::Stream *s) const = 0;
+ bool Verify(Stream *s) const;
+ virtual void Dump(Stream *s) const = 0;
/// Get the data that contains the DIE information for this unit.
///
/// This will return the correct bytes that contain the data for
@@ -122,7 +128,7 @@ public:
///
/// \return
/// The correct data for the DIE information in this unit.
- const lldb_private::DWARFDataExtractor &GetData() const;
+ const DWARFDataExtractor &GetData() const;
/// Get the size in bytes of the unit header.
///
@@ -151,9 +157,9 @@ public:
// Size of the CU data (without initial length and without header).
size_t GetDebugInfoSize() const;
// Size of the CU data incl. header but without initial length.
- uint32_t GetLength() const { return m_header.GetLength(); }
+ dw_offset_t GetLength() const { return m_header.GetLength(); }
uint16_t GetVersion() const { return m_header.GetVersion(); }
- const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
+ const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
dw_offset_t GetAbbrevOffset() const;
uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); }
dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); }
@@ -207,10 +213,10 @@ public:
bool GetIsOptimized();
- const lldb_private::FileSpec &GetCompilationDirectory();
- const lldb_private::FileSpec &GetAbsolutePath();
- lldb_private::FileSpec GetFile(size_t file_idx);
- lldb_private::FileSpec::Style GetPathStyle();
+ const FileSpec &GetCompilationDirectory();
+ const FileSpec &GetAbsolutePath();
+ FileSpec GetFile(size_t file_idx);
+ FileSpec::Style GetPathStyle();
SymbolFileDWARFDwo *GetDwoSymbolFile();
@@ -224,7 +230,9 @@ public:
uint8_t GetUnitType() const { return m_header.GetUnitType(); }
bool IsTypeUnit() const { return m_header.IsTypeUnit(); }
/// Note that this check only works for DWARF5+.
- bool IsSkeletonUnit() const { return GetUnitType() == llvm::dwarf::DW_UT_skeleton; }
+ bool IsSkeletonUnit() const {
+ return GetUnitType() == llvm::dwarf::DW_UT_skeleton;
+ }
std::optional<uint64_t> GetStringOffsetSectionItem(uint32_t index) const;
@@ -256,9 +264,9 @@ public:
/// Return the location table for parsing the given location list data. The
/// format is chosen according to the unit type. Never returns null.
std::unique_ptr<llvm::DWARFLocationTable>
- GetLocationTable(const lldb_private::DataExtractor &data) const;
+ GetLocationTable(const DataExtractor &data) const;
- lldb_private::DWARFDataExtractor GetLocationData() const;
+ DWARFDataExtractor GetLocationData() const;
/// Returns true if any DIEs in the unit match any DW_TAG values in \a tags.
///
@@ -269,7 +277,6 @@ public:
/// True if any DIEs match any tag in \a tags, false otherwise.
bool HasAny(llvm::ArrayRef<dw_tag_t> tags);
-
/// Get the fission .dwo file specific error for this compile unit.
///
/// The skeleton compile unit only can have a DWO error. Any other type
@@ -278,7 +285,7 @@ public:
/// \returns
/// A valid DWO error if there is a problem with anything in the
/// locating or parsing inforamtion in the .dwo file
- const lldb_private::Status &GetDwoError() const { return m_dwo_error; }
+ const Status &GetDwoError() const { return m_dwo_error; }
/// Set the fission .dwo file specific error for this compile unit.
///
@@ -286,16 +293,16 @@ public:
/// .dwo file. Things like a missing .dwo file, DWO ID mismatch, and other
/// .dwo errors can be stored in each compile unit so the issues can be
/// communicated to the user.
- void SetDwoError(const lldb_private::Status &error) { m_dwo_error = error; }
+ void SetDwoError(const Status &error) { m_dwo_error = error; }
protected:
DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
- const DWARFAbbreviationDeclarationSet &abbrevs,
+ const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo);
llvm::Error ExtractHeader(SymbolFileDWARF &dwarf,
- const lldb_private::DWARFDataExtractor &data,
+ const DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
// Get the DWARF unit DWARF debug information entry. Parse the single DIE
@@ -318,12 +325,12 @@ protected:
const std::optional<llvm::DWARFDebugRnglistTable> &GetRnglistTable();
- lldb_private::DWARFDataExtractor GetRnglistData() const;
+ DWARFDataExtractor GetRnglistData() const;
SymbolFileDWARF &m_dwarf;
std::shared_ptr<DWARFUnit> m_dwo;
DWARFUnitHeader m_header;
- const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
+ const llvm::DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
void *m_user_data = nullptr;
// The compile unit debug information entry item
DWARFDebugInfoEntry::collection m_die_array;
@@ -345,12 +352,12 @@ protected:
DWARFProducer m_producer = eProducerInvalid;
llvm::VersionTuple m_producer_version;
std::optional<uint64_t> m_language_type;
- lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
- std::optional<lldb_private::FileSpec> m_comp_dir;
- std::optional<lldb_private::FileSpec> m_file_spec;
- std::optional<dw_addr_t> m_addr_base; ///< Value of DW_AT_addr_base.
- dw_addr_t m_loclists_base = 0; ///< Value of DW_AT_loclists_base.
- dw_addr_t m_ranges_base = 0; ///< Value of DW_AT_rnglists_base.
+ LazyBool m_is_optimized = eLazyBoolCalculate;
+ std::optional<FileSpec> m_comp_dir;
+ std::optional<FileSpec> m_file_spec;
+ std::optional<dw_addr_t> m_addr_base; ///< Value of DW_AT_addr_base.
+ dw_addr_t m_loclists_base = 0; ///< Value of DW_AT_loclists_base.
+ dw_addr_t m_ranges_base = 0; ///< Value of DW_AT_rnglists_base.
std::optional<uint64_t> m_gnu_addr_base;
std::optional<uint64_t> m_gnu_ranges_base;
@@ -371,7 +378,7 @@ protected:
/// If we get an error when trying to load a .dwo file, save that error here.
/// Errors include .dwo/.dwp file not found, or the .dwp/.dwp file was found
/// but DWO ID doesn't match, etc.
- lldb_private::Status m_dwo_error;
+ Status m_dwo_error;
private:
void ParseProducerInfo();
@@ -387,5 +394,7 @@ private:
DWARFUnit(const DWARFUnit &) = delete;
const DWARFUnit &operator=(const DWARFUnit &) = delete;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index af2d6c554140..7c253553d57b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -18,6 +18,7 @@
using namespace lldb_private;
using namespace lldb;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
@@ -36,19 +37,29 @@ llvm::DenseSet<dw_offset_t>
DebugNamesDWARFIndex::GetUnits(const DebugNames &debug_names) {
llvm::DenseSet<dw_offset_t> result;
for (const DebugNames::NameIndex &ni : debug_names) {
- for (uint32_t cu = 0; cu < ni.getCUCount(); ++cu)
+ const uint32_t num_cus = ni.getCUCount();
+ for (uint32_t cu = 0; cu < num_cus; ++cu)
result.insert(ni.getCUOffset(cu));
+ const uint32_t num_tus = ni.getLocalTUCount();
+ for (uint32_t tu = 0; tu < num_tus; ++tu)
+ result.insert(ni.getLocalTUOffset(tu));
}
return result;
}
std::optional<DIERef>
DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
- std::optional<uint64_t> cu_offset = entry.getCUOffset();
- if (!cu_offset)
- return std::nullopt;
+ // Look for a DWARF unit offset (CU offset or local TU offset) as they are
+ // both offsets into the .debug_info section.
+ std::optional<uint64_t> unit_offset = entry.getCUOffset();
+ if (!unit_offset) {
+ unit_offset = entry.getLocalTUOffset();
+ if (!unit_offset)
+ return std::nullopt;
+ }
- DWARFUnit *cu = m_debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, *cu_offset);
+ DWARFUnit *cu =
+ m_debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, *unit_offset);
if (!cu)
return std::nullopt;
@@ -128,8 +139,19 @@ void DebugNamesDWARFIndex::GetGlobalVariables(
DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
uint64_t cu_offset = cu.GetOffset();
bool found_entry_for_cu = false;
- for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
- for (DebugNames::NameTableEntry nte: ni) {
+ for (const DebugNames::NameIndex &ni : *m_debug_names_up) {
+ // Check if this name index contains an entry for the given CU.
+ bool cu_matches = false;
+ for (uint32_t i = 0; i < ni.getCUCount(); ++i) {
+ if (ni.getCUOffset(i) == cu_offset) {
+ cu_matches = true;
+ break;
+ }
+ }
+ if (!cu_matches)
+ continue;
+
+ for (DebugNames::NameTableEntry nte : ni) {
uint64_t entry_offset = nte.getEntryOffset();
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
@@ -227,7 +249,7 @@ void DebugNamesDWARFIndex::GetNamespaces(
ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
- dwarf::Tag entry_tag = entry.tag();
+ lldb_private::dwarf::Tag entry_tag = entry.tag();
if (entry_tag == DW_TAG_namespace ||
entry_tag == DW_TAG_imported_declaration) {
if (!ProcessEntry(entry, callback))
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
index abbd700f1603..7ce630a56137 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
@@ -17,7 +17,8 @@
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include <optional>
-namespace lldb_private {
+namespace lldb_private::plugin {
+namespace dwarf {
class DebugNamesDWARFIndex : public DWARFIndex {
public:
static llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
@@ -89,6 +90,7 @@ private:
static llvm::DenseSet<dw_offset_t> GetUnits(const DebugNames &debug_names);
};
-} // namespace lldb_private
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H
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 57b962ff60df..16ff5f7d4842 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -28,6 +28,7 @@
using namespace lldb_private;
using namespace lldb;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
void ManualDWARFIndex::Index() {
if (m_indexed)
@@ -654,7 +655,7 @@ void ManualDWARFIndex::IndexSet::Encode(DataEncoder &encoder) const {
// Now that all strings have been gathered, we will emit the string table.
strtab.Encode(encoder);
- // Followed the the symbol table data.
+ // Followed by the symbol table data.
encoder.AppendData(index_encoder.GetData());
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
index d95cf501face..0126e587e52d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -13,10 +13,11 @@
#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
#include "llvm/ADT/DenseSet.h"
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFDebugInfo;
class SymbolFileDWARFDwo;
-namespace lldb_private {
class ManualDWARFIndex : public DWARFIndex {
public:
ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf,
@@ -173,6 +174,7 @@ private:
IndexSet m_set;
bool m_indexed = false;
};
-} // namespace lldb_private
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
index 89e628f5eaf1..44d90648700c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -20,6 +20,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
void NameToDIE::Finalize() {
m_map.Sort(std::less<DIERef>());
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 61df1a628ab5..90eac1fa3733 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -16,6 +16,8 @@
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-defines.h"
+namespace lldb_private::plugin {
+namespace dwarf {
class DWARFUnit;
class NameToDIE {
@@ -24,18 +26,18 @@ public:
~NameToDIE() = default;
- void Dump(lldb_private::Stream *s);
+ void Dump(Stream *s);
- void Insert(lldb_private::ConstString name, const DIERef &die_ref);
+ void Insert(ConstString name, const DIERef &die_ref);
void Append(const NameToDIE &other);
void Finalize();
- bool Find(lldb_private::ConstString name,
+ bool Find(ConstString name,
llvm::function_ref<bool(DIERef ref)> callback) const;
- bool Find(const lldb_private::RegularExpression &regex,
+ bool Find(const RegularExpression &regex,
llvm::function_ref<bool(DIERef ref)> callback) const;
/// \a unit must be the skeleton unit if possible, not GetNonSkeletonUnit().
@@ -44,8 +46,7 @@ public:
llvm::function_ref<bool(DIERef ref)> callback) const;
void
- ForEach(std::function<bool(lldb_private::ConstString name,
- const DIERef &die_ref)> const
+ ForEach(std::function<bool(ConstString name, const DIERef &die_ref)> const
&callback) const;
/// Decode a serialized version of this object from data.
@@ -61,9 +62,8 @@ public:
/// All strings in cache files are put into string tables for efficiency
/// and cache file size reduction. Strings are stored as uint32_t string
/// table offsets in the cache data.
- bool Decode(const lldb_private::DataExtractor &data,
- lldb::offset_t *offset_ptr,
- const lldb_private::StringTableReader &strtab);
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ const StringTableReader &strtab);
/// Encode this object into a data encoder object.
///
@@ -76,8 +76,7 @@ public:
/// All strings in cache files are put into string tables for efficiency
/// and cache file size reduction. Strings are stored as uint32_t string
/// table offsets in the cache data.
- void Encode(lldb_private::DataEncoder &encoder,
- lldb_private::ConstStringTable &strtab) const;
+ void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
/// Used for unit testing the encoding and decoding.
bool operator==(const NameToDIE &rhs) const;
@@ -87,7 +86,9 @@ public:
void Clear() { m_map.Clear(); }
protected:
- lldb_private::UniqueCStringMap<DIERef> m_map;
+ UniqueCStringMap<DIERef> m_map;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H
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 6e5482dba9d2..505ea29ca4d4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -10,6 +10,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/Threading.h"
#include "lldb/Core/Module.h"
@@ -18,13 +19,13 @@
#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"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/Timer.h"
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
@@ -45,7 +46,6 @@
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/LineTable.h"
-#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
@@ -59,7 +59,6 @@
#include "DWARFASTParser.h"
#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
-#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugMacro.h"
@@ -75,6 +74,7 @@
#include "SymbolFileDWARFDwo.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
@@ -98,6 +98,7 @@
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
LLDB_PLUGIN_DEFINE(SymbolFileDWARF)
@@ -115,8 +116,8 @@ enum {
class PluginProperties : public Properties {
public:
- static ConstString GetSettingName() {
- return ConstString(SymbolFileDWARF::GetPluginNameStatic());
+ static llvm::StringRef GetSettingName() {
+ return SymbolFileDWARF::GetPluginNameStatic();
}
PluginProperties() {
@@ -131,15 +132,19 @@ public:
} // namespace
+bool IsStructOrClassTag(llvm::dwarf::Tag Tag) {
+ return Tag == llvm::dwarf::Tag::DW_TAG_class_type ||
+ Tag == llvm::dwarf::Tag::DW_TAG_structure_type;
+}
+
static PluginProperties &GetGlobalPluginProperties() {
static PluginProperties g_settings;
return g_settings;
}
static const llvm::DWARFDebugLine::LineTable *
-ParseLLVMLineTable(lldb_private::DWARFContext &context,
- llvm::DWARFDebugLine &line, dw_offset_t line_offset,
- dw_offset_t unit_offset) {
+ParseLLVMLineTable(DWARFContext &context, llvm::DWARFDebugLine &line,
+ dw_offset_t line_offset, dw_offset_t unit_offset) {
Log *log = GetLog(DWARFLog::DebugInfo);
llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF();
@@ -160,7 +165,7 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context,
return *line_table;
}
-static bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context,
+static bool ParseLLVMLineTablePrologue(DWARFContext &context,
llvm::DWARFDebugLine::Prologue &prologue,
dw_offset_t line_offset,
dw_offset_t unit_offset) {
@@ -210,17 +215,24 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
FileSpec::Style style,
llvm::StringRef compile_dir = {}) {
FileSpecList support_files;
- size_t first_file = 0;
- if (prologue.getVersion() <= 4) {
- // File index 0 is not valid before DWARF v5. Add a dummy entry to ensure
- // support file list indices match those we get from the debug info and line
- // tables.
+
+ // Handle the case where there are no files first to avoid having to special
+ // case this later.
+ if (prologue.FileNames.empty())
+ return support_files;
+
+ // Before DWARF v5, the line table indexes were one based.
+ const bool is_one_based = prologue.getVersion() < 5;
+ const size_t file_names = prologue.FileNames.size();
+ const size_t first_file_idx = is_one_based ? 1 : 0;
+ const size_t last_file_idx = is_one_based ? file_names : file_names - 1;
+
+ // Add a dummy entry to ensure the support file list indices match those we
+ // get from the debug info and line tables.
+ if (is_one_based)
support_files.Append(FileSpec());
- first_file = 1;
- }
- const size_t number_of_files = prologue.FileNames.size();
- for (size_t idx = first_file; idx <= number_of_files; ++idx) {
+ for (size_t idx = first_file_idx; idx <= last_file_idx; ++idx) {
std::string remapped_file;
if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) {
if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))
@@ -229,8 +241,15 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
remapped_file = std::move(*file_path);
}
+ Checksum checksum;
+ if (prologue.ContentTypes.HasMD5) {
+ const llvm::DWARFDebugLine::FileNameEntry &file_name_entry =
+ prologue.getFileNameEntry(idx);
+ checksum = file_name_entry.Checksum;
+ }
+
// Unconditionally add an entry, so the indices match up.
- support_files.EmplaceBack(remapped_file, style);
+ support_files.EmplaceBack(remapped_file, style, checksum);
}
return support_files;
@@ -512,6 +531,21 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
return version >= 2 && version <= 5;
}
+static std::set<dw_form_t>
+GetUnsupportedForms(llvm::DWARFDebugAbbrev *debug_abbrev) {
+ if (!debug_abbrev)
+ return {};
+
+ std::set<dw_form_t> unsupported_forms;
+ for (const auto &[_, decl_set] : *debug_abbrev)
+ for (const auto &decl : decl_set)
+ for (const auto &attr : decl.attributes())
+ if (!DWARFFormValue::FormIsSupported(attr.Form))
+ unsupported_forms.insert(attr.Form);
+
+ return unsupported_forms;
+}
+
uint32_t SymbolFileDWARF::CalculateAbilities() {
uint32_t abilities = 0;
if (m_objfile_sp != nullptr) {
@@ -540,20 +574,16 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
if (section)
debug_abbrev_file_size = section->GetFileSize();
- DWARFDebugAbbrev *abbrev = DebugAbbrev();
- if (abbrev) {
- std::set<dw_form_t> invalid_forms;
- abbrev->GetUnsupportedForms(invalid_forms);
- if (!invalid_forms.empty()) {
- StreamString error;
- error.Printf("unsupported DW_FORM value%s:",
- invalid_forms.size() > 1 ? "s" : "");
- for (auto form : invalid_forms)
- error.Printf(" %#x", form);
- m_objfile_sp->GetModule()->ReportWarning(
- "{0}", error.GetString().str().c_str());
- return 0;
- }
+ llvm::DWARFDebugAbbrev *abbrev = DebugAbbrev();
+ std::set<dw_form_t> unsupported_forms = GetUnsupportedForms(abbrev);
+ if (!unsupported_forms.empty()) {
+ StreamString error;
+ error.Printf("unsupported DW_FORM value%s:",
+ unsupported_forms.size() > 1 ? "s" : "");
+ for (auto form : unsupported_forms)
+ error.Printf(" %#x", form);
+ m_objfile_sp->GetModule()->ReportWarning("{0}", error.GetString());
+ return 0;
}
section =
@@ -615,7 +645,7 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
m_objfile_sp->ReadSectionData(section_sp.get(), data);
}
-DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
+llvm::DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (m_abbr)
return m_abbr.get();
@@ -623,8 +653,9 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (debug_abbrev_data.GetByteSize() == 0)
return nullptr;
- auto abbr = std::make_unique<DWARFDebugAbbrev>();
- llvm::Error error = abbr->parse(debug_abbrev_data);
+ auto abbr =
+ std::make_unique<llvm::DWARFDebugAbbrev>(debug_abbrev_data.GetAsLLVM());
+ llvm::Error error = abbr->parse();
if (error) {
Log *log = GetLog(DWARFLog::DebugInfo);
LLDB_LOG_ERROR(log, std::move(error),
@@ -1441,6 +1472,17 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
return CompilerDeclContext();
}
+std::vector<CompilerContext>
+SymbolFileDWARF::GetCompilerContextForUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ // Anytime we have a lldb::user_id_t, we must get the DIE by calling
+ // SymbolFileDWARF::GetDIE(). See comments inside the
+ // SymbolFileDWARF::GetDIE() for details.
+ if (DWARFDIE die = GetDIE(type_uid))
+ return die.GetDeclContext();
+ return {};
+}
+
Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
@@ -1508,11 +1550,11 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
// This function is used when SymbolFileDWARFDebugMap owns a bunch of
// SymbolFileDWARF objects to detect if this DWARF file is the one that can
// resolve a compiler_type.
-bool SymbolFileDWARF::HasForwardDeclForClangType(
+bool SymbolFileDWARF::HasForwardDeclForCompilerType(
const CompilerType &compiler_type) {
CompilerType compiler_type_no_qualifiers =
ClangUtil::RemoveFastQualifiers(compiler_type);
- if (GetForwardDeclClangTypeToDie().count(
+ if (GetForwardDeclCompilerTypeToDIE().count(
compiler_type_no_qualifiers.GetOpaqueQualType())) {
return true;
}
@@ -1540,9 +1582,9 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
// We have a struct/union/class/enum that needs to be fully resolved.
CompilerType compiler_type_no_qualifiers =
ClangUtil::RemoveFastQualifiers(compiler_type);
- auto die_it = GetForwardDeclClangTypeToDie().find(
+ auto die_it = GetForwardDeclCompilerTypeToDIE().find(
compiler_type_no_qualifiers.GetOpaqueQualType());
- if (die_it == GetForwardDeclClangTypeToDie().end()) {
+ if (die_it == GetForwardDeclCompilerTypeToDIE().end()) {
// We have already resolved this type...
return true;
}
@@ -1553,7 +1595,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
// declaration map in case anyone child members or other types require this
// type to get resolved. The type will get resolved when all of the calls
// to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done.
- GetForwardDeclClangTypeToDie().erase(die_it);
+ GetForwardDeclCompilerTypeToDIE().erase(die_it);
Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
@@ -1729,38 +1771,129 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())
return dwp_sp;
- const char *comp_dir = nullptr;
FileSpec dwo_file(dwo_name);
FileSystem::Instance().Resolve(dwo_file);
- if (dwo_file.IsRelative()) {
- comp_dir = cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir,
- nullptr);
- if (!comp_dir) {
- unit.SetDwoError(Status::createWithFormat(
- "unable to locate relative .dwo debug file \"{0}\" for "
- "skeleton DIE {1:x16} without valid DW_AT_comp_dir "
- "attribute",
- dwo_name, cu_die.GetOffset()));
- return nullptr;
+ bool found = false;
+
+ const FileSpecList &debug_file_search_paths =
+ Target::GetDefaultDebugFileSearchPaths();
+ size_t num_search_paths = debug_file_search_paths.GetSize();
+
+ // It's relative, e.g. "foo.dwo", but we just to happen to be right next to
+ // it. Or it's absolute.
+ found = FileSystem::Instance().Exists(dwo_file);
+
+ const char *comp_dir =
+ cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr);
+ if (!found) {
+ // It could be a relative path that also uses DW_AT_COMP_DIR.
+ if (comp_dir) {
+ dwo_file.SetFile(comp_dir, FileSpec::Style::native);
+ if (!dwo_file.IsRelative()) {
+ FileSystem::Instance().Resolve(dwo_file);
+ dwo_file.AppendPathComponent(dwo_name);
+ found = FileSystem::Instance().Exists(dwo_file);
+ } else {
+ FileSpecList dwo_paths;
+
+ // 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.
+ FileSpec relative_to_binary = dwo_file;
+ relative_to_binary.PrependPathComponent(
+ m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
+ FileSystem::Instance().Resolve(relative_to_binary);
+ relative_to_binary.AppendPathComponent(dwo_name);
+ dwo_paths.Append(relative_to_binary);
+
+ // Or it's relative to one of the user specified debug directories.
+ for (size_t idx = 0; idx < num_search_paths; ++idx) {
+ FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+ dirspec.AppendPathComponent(comp_dir);
+ FileSystem::Instance().Resolve(dirspec);
+ if (!FileSystem::Instance().IsDirectory(dirspec))
+ continue;
+
+ dirspec.AppendPathComponent(dwo_name);
+ dwo_paths.Append(dirspec);
+ }
+
+ size_t num_possible = dwo_paths.GetSize();
+ for (size_t idx = 0; idx < num_possible && !found; ++idx) {
+ FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);
+ if (FileSystem::Instance().Exists(dwo_spec)) {
+ dwo_file = dwo_spec;
+ found = true;
+ }
+ }
+ }
+ } else {
+ Log *log = GetLog(LLDBLog::Symbols);
+ LLDB_LOGF(log,
+ "unable to locate relative .dwo debug file \"%s\" for "
+ "skeleton DIE 0x%016" PRIx64 " without valid DW_AT_comp_dir "
+ "attribute",
+ dwo_name, cu_die.GetOffset());
+ }
+ }
+
+ if (!found) {
+ // Try adding the DW_AT_dwo_name ( e.g. "c/d/main-main.dwo"), and just the
+ // filename ("main-main.dwo") to binary dir and search paths.
+ FileSpecList dwo_paths;
+ FileSpec dwo_name_spec(dwo_name);
+ llvm::StringRef filename_only = dwo_name_spec.GetFilename();
+
+ FileSpec binary_directory(
+ m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
+ FileSystem::Instance().Resolve(binary_directory);
+
+ if (dwo_name_spec.IsRelative()) {
+ FileSpec dwo_name_binary_directory(binary_directory);
+ dwo_name_binary_directory.AppendPathComponent(dwo_name);
+ dwo_paths.Append(dwo_name_binary_directory);
+ }
+
+ FileSpec filename_binary_directory(binary_directory);
+ filename_binary_directory.AppendPathComponent(filename_only);
+ dwo_paths.Append(filename_binary_directory);
+
+ for (size_t idx = 0; idx < num_search_paths; ++idx) {
+ FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+ FileSystem::Instance().Resolve(dirspec);
+ if (!FileSystem::Instance().IsDirectory(dirspec))
+ continue;
+
+ FileSpec dwo_name_dirspec(dirspec);
+ dwo_name_dirspec.AppendPathComponent(dwo_name);
+ dwo_paths.Append(dwo_name_dirspec);
+
+ FileSpec filename_dirspec(dirspec);
+ filename_dirspec.AppendPathComponent(filename_only);
+ dwo_paths.Append(filename_dirspec);
}
- 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());
+ size_t num_possible = dwo_paths.GetSize();
+ for (size_t idx = 0; idx < num_possible && !found; ++idx) {
+ FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);
+ if (FileSystem::Instance().Exists(dwo_spec)) {
+ dwo_file = dwo_spec;
+ found = true;
+ }
}
- FileSystem::Instance().Resolve(dwo_file);
- dwo_file.AppendPathComponent(dwo_name);
}
- if (!FileSystem::Instance().Exists(dwo_file)) {
+ if (!found) {
+ FileSpec error_dwo_path(dwo_name);
+ FileSystem::Instance().Resolve(error_dwo_path);
+ if (error_dwo_path.IsRelative() && comp_dir != nullptr) {
+ error_dwo_path.PrependPathComponent(comp_dir);
+ FileSystem::Instance().Resolve(error_dwo_path);
+ }
unit.SetDwoError(Status::createWithFormat(
"unable to locate .dwo debug file \"{0}\" for skeleton DIE "
"{1:x16}",
- dwo_file.GetPath().c_str(), cu_die.GetOffset()));
+ error_dwo_path.GetPath().c_str(), cu_die.GetOffset()));
if (m_dwo_warning_issued.test_and_set(std::memory_order_relaxed) == false) {
GetObjectFile()->GetModule()->ReportWarning(
@@ -1849,7 +1982,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
// (corresponding to .dwo) so we simply skip it.
if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" &&
llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())
- .endswith(dwo_module_spec.GetFileSpec().GetPath())) {
+ .ends_with(dwo_module_spec.GetFileSpec().GetPath())) {
continue;
}
@@ -2331,7 +2464,7 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx,
// ...But if we are only checking root decl contexts, confirm that the
// 'die' is a top-level context.
if (only_root_namespaces)
- return die.GetParent().Tag() == dwarf::DW_TAG_compile_unit;
+ return die.GetParent().Tag() == llvm::dwarf::DW_TAG_compile_unit;
return true;
}
@@ -2463,178 +2596,157 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
}
}
-void SymbolFileDWARF::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- // Make sure we haven't already searched this SymbolFile before.
- if (!searched_symbol_files.insert(this).second)
- return;
-
- Log *log = GetLog(DWARFLog::Lookups);
+/// Split a name up into a basename and template parameters.
+static bool SplitTemplateParams(llvm::StringRef fullname,
+ llvm::StringRef &basename,
+ llvm::StringRef &template_params) {
+ auto it = fullname.find('<');
+ if (it == llvm::StringRef::npos) {
+ basename = fullname;
+ template_params = llvm::StringRef();
+ return false;
+ }
+ basename = fullname.slice(0, it);
+ template_params = fullname.slice(it, fullname.size());
+ return true;
+}
- if (log) {
- if (parent_decl_ctx)
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx = "
- "{1:p} (\"{2}\"), max_matches={3}, type_list)",
- name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
- parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches);
- else
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx = "
- "NULL, max_matches={1}, type_list)",
- name.GetCString(), max_matches);
+static bool UpdateCompilerContextForSimpleTemplateNames(TypeQuery &match) {
+ // We need to find any names in the context that have template parameters
+ // and strip them so the context can be matched when -gsimple-template-names
+ // is being used. Returns true if any of the context items were updated.
+ bool any_context_updated = false;
+ for (auto &context : match.GetContextRef()) {
+ llvm::StringRef basename, params;
+ if (SplitTemplateParams(context.name.GetStringRef(), basename, params)) {
+ context.name = ConstString(basename);
+ any_context_updated = true;
+ }
}
+ return any_context_updated;
+}
+void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ // Make sure we haven't already searched this SymbolFile before.
+ if (results.AlreadySearched(this))
return;
- // Unlike FindFunctions(), FindTypes() following cannot produce false
- // positives.
-
- const llvm::StringRef name_ref = name.GetStringRef();
- auto name_bracket_index = name_ref.find('<');
- m_index->GetTypes(name, [&](DWARFDIE die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- return true; // The containing decl contexts don't match
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- Type *matching_type = ResolveType(die, true, true);
- if (!matching_type)
- return true;
+ bool have_index_match = false;
+ m_index->GetTypes(query.GetTypeBasename(), [&](DWARFDIE die) {
+ // Check the language, but only if we have a language filter.
+ if (query.HasLanguage()) {
+ if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
+ return true; // Keep iterating over index types, language mismatch.
+ }
- // With -gsimple-template-names, a templated type's DW_AT_name will not
- // contain the template parameters. Make sure that if the original query
- // didn't contain a '<', we filter out entries with template parameters.
- if (name_bracket_index == llvm::StringRef::npos &&
- matching_type->IsTemplateType())
- return true;
+ // Check the context matches
+ std::vector<lldb_private::CompilerContext> die_context;
+ if (query.GetModuleSearch())
+ die_context = die.GetDeclContext();
+ else
+ die_context = die.GetTypeLookupContext();
+ assert(!die_context.empty());
+ if (!query.ContextMatches(die_context))
+ return true; // Keep iterating over index types, context mismatch.
- // We found a type pointer, now find the shared pointer form our type
- // list
- types.InsertUnique(matching_type->shared_from_this());
- return types.GetSize() < max_matches;
+ // Try to resolve the type.
+ if (Type *matching_type = ResolveType(die, true, true)) {
+ if (matching_type->IsTemplateType()) {
+ // We have to watch out for case where we lookup a type by basename and
+ // it matches a template with simple template names. Like looking up
+ // "Foo" and if we have simple template names then we will match
+ // "Foo<int>" and "Foo<double>" because all the DWARF has is "Foo" in
+ // the accelerator tables. The main case we see this in is when the
+ // expression parser is trying to parse "Foo<int>" and it will first do
+ // a lookup on just "Foo". We verify the type basename matches before
+ // inserting the type in the results.
+ auto CompilerTypeBasename =
+ matching_type->GetForwardCompilerType().GetTypeName(true);
+ if (CompilerTypeBasename != query.GetTypeBasename())
+ return true; // Keep iterating over index types, basename mismatch.
+ }
+ have_index_match = true;
+ results.InsertUnique(matching_type->shared_from_this());
+ }
+ return !results.Done(query); // Keep iterating if we aren't done.
});
+ if (results.Done(query))
+ return;
+
// With -gsimple-template-names, a templated type's DW_AT_name will not
// contain the template parameters. Try again stripping '<' and anything
// after, filtering out entries with template parameters that don't match.
- if (types.GetSize() < max_matches) {
- if (name_bracket_index != llvm::StringRef::npos) {
- const llvm::StringRef name_no_template_params =
- name_ref.slice(0, name_bracket_index);
- const llvm::StringRef template_params =
- name_ref.slice(name_bracket_index, name_ref.size());
- m_index->GetTypes(ConstString(name_no_template_params), [&](DWARFDIE die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- return true; // The containing decl contexts don't match
-
- const llvm::StringRef base_name = GetTypeForDIE(die)->GetBaseName().AsCString();
- auto it = base_name.find('<');
- // If the candidate qualified name doesn't have '<', it doesn't have
- // template params to compare.
- if (it == llvm::StringRef::npos)
- return true;
-
- // Filter out non-matching instantiations by comparing template params.
- const llvm::StringRef base_name_template_params =
- base_name.slice(it, base_name.size());
-
- if (template_params != base_name_template_params)
- return true;
-
- Type *matching_type = ResolveType(die, true, true);
- if (!matching_type)
- return true;
+ if (!have_index_match) {
+ // Create a type matcher with a compiler context that is tuned for
+ // -gsimple-template-names. We will use this for the index lookup and the
+ // context matching, but will use the original "match" to insert matches
+ // into if things match. The "match_simple" has a compiler context with
+ // all template parameters removed to allow the names and context to match.
+ // The UpdateCompilerContextForSimpleTemplateNames(...) will return true if
+ // it trims any context items down by removing template parameter names.
+ TypeQuery query_simple(query);
+ if (UpdateCompilerContextForSimpleTemplateNames(query_simple)) {
+
+ // Copy our match's context and update the basename we are looking for
+ // so we can use this only to compare the context correctly.
+ m_index->GetTypes(query_simple.GetTypeBasename(), [&](DWARFDIE die) {
+ // Check the language, but only if we have a language filter.
+ if (query.HasLanguage()) {
+ if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
+ return true; // Keep iterating over index types, language mismatch.
+ }
- // We found a type pointer, now find the shared pointer form our type
- // list.
- types.InsertUnique(matching_type->shared_from_this());
- return types.GetSize() < max_matches;
+ // Check the context matches
+ std::vector<lldb_private::CompilerContext> die_context;
+ if (query.GetModuleSearch())
+ die_context = die.GetDeclContext();
+ else
+ die_context = die.GetTypeLookupContext();
+ assert(!die_context.empty());
+ if (!query_simple.ContextMatches(die_context))
+ return true; // Keep iterating over index types, context mismatch.
+
+ // Try to resolve the type.
+ if (Type *matching_type = ResolveType(die, true, true)) {
+ ConstString name = matching_type->GetQualifiedName();
+ // We have found a type that still might not match due to template
+ // parameters. If we create a new TypeQuery that uses the new type's
+ // fully qualified name, we can find out if this type matches at all
+ // context levels. We can't use just the "match_simple" context
+ // because all template parameters were stripped off. The fully
+ // qualified name of the type will have the template parameters and
+ // will allow us to make sure it matches correctly.
+ TypeQuery die_query(name.GetStringRef(),
+ TypeQueryOptions::e_exact_match);
+ if (!query.ContextMatches(die_query.GetContextRef()))
+ return true; // Keep iterating over index types, context mismatch.
+
+ results.InsertUnique(matching_type->shared_from_this());
+ }
+ return !results.Done(query); // Keep iterating if we aren't done.
});
+ if (results.Done(query))
+ return;
}
}
// Next search through the reachable Clang modules. This only applies for
// DWARF objects compiled with -gmodules that haven't been processed by
// dsymutil.
- if (types.GetSize() < max_matches) {
- UpdateExternalModuleListIfNeeded();
-
- for (const auto &pair : m_external_type_modules)
- if (ModuleSP external_module_sp = pair.second)
- if (SymbolFile *sym_file = external_module_sp->GetSymbolFile())
- sym_file->FindTypes(name, parent_decl_ctx, max_matches,
- searched_symbol_files, types);
- }
+ UpdateExternalModuleListIfNeeded();
- if (log && types.GetSize()) {
- if (parent_decl_ctx) {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx "
- "= {1:p} (\"{2}\"), max_matches={3}, type_list) => {4}",
- name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
- parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches,
- types.GetSize());
- } else {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx "
- "= NULL, max_matches={1}, type_list) => {2}",
- name.GetCString(), max_matches, types.GetSize());
+ for (const auto &pair : m_external_type_modules) {
+ if (ModuleSP external_module_sp = pair.second) {
+ external_module_sp->FindTypes(query, results);
+ if (results.Done(query))
+ return;
}
}
}
-void SymbolFileDWARF::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- // Make sure we haven't already searched this SymbolFile before.
- if (!searched_symbol_files.insert(this).second)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- if (pattern.empty())
- return;
-
- ConstString name = pattern.back().name;
-
- if (!name)
- return;
-
- m_index->GetTypes(name, [&](DWARFDIE die) {
- if (!languages[GetLanguageFamily(*die.GetCU())])
- return true;
-
- llvm::SmallVector<CompilerContext, 4> die_context;
- die.GetDeclContext(die_context);
- if (!contextMatches(die_context, pattern))
- return true;
-
- if (Type *matching_type = ResolveType(die, true, true)) {
- // We found a type pointer, now find the shared pointer form our type
- // list.
- types.InsertUnique(matching_type->shared_from_this());
- }
- return true;
- });
-
- // Next search through the reachable Clang modules. This only applies for
- // DWARF objects compiled with -gmodules that haven't been processed by
- // dsymutil.
- UpdateExternalModuleListIfNeeded();
-
- for (const auto &pair : m_external_type_modules)
- if (ModuleSP external_module_sp = pair.second)
- external_module_sp->FindTypes(pattern, languages, searched_symbol_files,
- types);
-}
-
CompilerDeclContext
SymbolFileDWARF::FindNamespace(ConstString name,
const CompilerDeclContext &parent_decl_ctx,
@@ -2820,29 +2932,18 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
m_index->GetCompleteObjCClass(
type_name, must_be_implementation, [&](DWARFDIE type_die) {
- bool try_resolving_type = false;
-
// Don't try and resolve the DIE we are looking for with the DIE
// itself!
- if (type_die != die) {
- switch (type_die.Tag()) {
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- try_resolving_type = true;
- break;
- default:
- break;
- }
- }
- if (!try_resolving_type)
+ if (type_die == die || !IsStructOrClassTag(type_die.Tag()))
return true;
if (must_be_implementation &&
- type_die.Supports_DW_AT_APPLE_objc_complete_type())
- try_resolving_type = type_die.GetAttributeValueAsUnsigned(
+ type_die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ const bool try_resolving_type = type_die.GetAttributeValueAsUnsigned(
DW_AT_APPLE_objc_complete_type, 0);
- if (!try_resolving_type)
- return true;
+ if (!try_resolving_type)
+ return true;
+ }
Type *resolved_type = ResolveType(type_die, false, true);
if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
@@ -2993,43 +3094,20 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
template_params = dwarf_ast->GetDIEClassTemplateParams(die);
}
- m_index->GetTypes(GetDWARFDeclContext(die), [&](DWARFDIE type_die) {
+ const DWARFDeclContext die_dwarf_decl_ctx = GetDWARFDeclContext(die);
+ m_index->GetTypes(die_dwarf_decl_ctx, [&](DWARFDIE type_die) {
// Make sure type_die's language matches the type system we are
// looking for. We don't want to find a "Foo" type from Java if we
// are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
if (type_system &&
!type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
return true;
- bool try_resolving_type = false;
- // Don't try and resolve the DIE we are looking for with the DIE
- // itself!
const dw_tag_t type_tag = type_die.Tag();
- // Make sure the tags match
- if (type_tag == tag) {
- // The tags match, lets try resolving this type
- try_resolving_type = true;
- } else {
- // The tags don't match, but we need to watch our for a forward
- // declaration for a struct and ("struct foo") ends up being a
- // class ("class foo { ... };") or vice versa.
- switch (type_tag) {
- case DW_TAG_class_type:
- // We had a "class foo", see if we ended up with a "struct foo
- // { ... };"
- try_resolving_type = (tag == DW_TAG_structure_type);
- break;
- case DW_TAG_structure_type:
- // We had a "struct foo", see if we ended up with a "class foo
- // { ... };"
- try_resolving_type = (tag == DW_TAG_class_type);
- break;
- default:
- // Tags don't match, don't event try to resolve using this type
- // whose name matches....
- break;
- }
- }
+ // Resolve the type if both have the same tag or {class, struct} tags.
+ const bool try_resolving_type =
+ type_tag == tag ||
+ (IsStructOrClassTag(type_tag) && IsStructOrClassTag(tag));
if (!try_resolving_type) {
if (log) {
@@ -3057,7 +3135,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
}
// Make sure the decl contexts match all the way up
- if (GetDWARFDeclContext(die) != type_dwarf_decl_ctx)
+ if (die_dwarf_decl_ctx != type_dwarf_decl_ctx)
return true;
Type *resolved_type = ResolveType(type_die, false);
@@ -3437,9 +3515,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}
// Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
- // for static constexpr member variables -- DW_AT_const_value will be
- // present in the class declaration and DW_AT_location in the DIE defining
- // the member.
+ // for static constexpr member variables -- DW_AT_const_value and
+ // DW_AT_location will both be present in the DIE defining the member.
bool location_is_const_value_data =
const_value_form.IsValid() && !location_form.IsValid();
@@ -4129,6 +4206,72 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) {
clang->Dump(s.AsRawOstream());
}
+bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary &d,
+ bool errors_only) {
+ StructuredData::Array separate_debug_info_files;
+ DWARFDebugInfo &info = DebugInfo();
+ const size_t num_cus = info.GetNumUnits();
+ for (size_t cu_idx = 0; cu_idx < num_cus; cu_idx++) {
+ DWARFUnit *unit = info.GetUnitAtIndex(cu_idx);
+ DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(unit);
+ if (dwarf_cu == nullptr)
+ continue;
+
+ // Check if this is a DWO unit by checking if it has a DWO ID.
+ // NOTE: it seems that `DWARFUnit::IsDWOUnit` is always false?
+ if (!dwarf_cu->GetDWOId().has_value())
+ continue;
+
+ StructuredData::DictionarySP dwo_data =
+ std::make_shared<StructuredData::Dictionary>();
+ const uint64_t dwo_id = dwarf_cu->GetDWOId().value();
+ dwo_data->AddIntegerItem("dwo_id", dwo_id);
+
+ if (const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly()) {
+ const char *dwo_name = GetDWOName(*dwarf_cu, *die.GetDIE());
+ if (dwo_name) {
+ dwo_data->AddStringItem("dwo_name", dwo_name);
+ } else {
+ dwo_data->AddStringItem("error", "missing dwo name");
+ }
+
+ const char *comp_dir = die.GetDIE()->GetAttributeValueAsString(
+ dwarf_cu, DW_AT_comp_dir, nullptr);
+ if (comp_dir) {
+ dwo_data->AddStringItem("comp_dir", comp_dir);
+ }
+ } else {
+ dwo_data->AddStringItem(
+ "error",
+ llvm::formatv("unable to get unit DIE for DWARFUnit at {0:x}",
+ dwarf_cu->GetOffset())
+ .str());
+ }
+
+ // If we have a DWO symbol file, that means we were able to successfully
+ // load it.
+ SymbolFile *dwo_symfile = dwarf_cu->GetDwoSymbolFile();
+ if (dwo_symfile) {
+ dwo_data->AddStringItem(
+ "resolved_dwo_path",
+ dwo_symfile->GetObjectFile()->GetFileSpec().GetPath());
+ } else {
+ dwo_data->AddStringItem("error",
+ dwarf_cu->GetDwoError().AsCString("unknown"));
+ }
+ dwo_data->AddBooleanItem("loaded", dwo_symfile != nullptr);
+ if (!errors_only || dwo_data->HasKey("error"))
+ separate_debug_info_files.AddItem(dwo_data);
+ }
+
+ d.AddStringItem("type", "dwo");
+ d.AddStringItem("symfile", GetMainObjectFile()->GetFileSpec().GetPath());
+ d.AddItem("separate-debug-info-files",
+ std::make_shared<StructuredData::Array>(
+ std::move(separate_debug_info_files)));
+ return true;
+}
+
SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
if (m_debug_map_symfile == nullptr) {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
@@ -4147,9 +4290,10 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
module_spec.GetSymbolFileSpec() =
FileSpec(m_objfile_sp->GetModule()->GetFileSpec().GetPath() + ".dwp");
+ module_spec.GetUUID() = m_objfile_sp->GetUUID();
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec dwp_filespec =
- Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+ PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
if (FileSystem::Instance().Exists(dwp_filespec)) {
DataBufferSP dwp_file_data_sp;
lldb::offset_t dwp_file_data_offset = 0;
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 191a5abcf265..78819edd0062 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -30,6 +30,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Flags.h"
#include "lldb/Utility/RangeMap.h"
+#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-private.h"
#include "DWARFContext.h"
@@ -38,10 +39,17 @@
#include "DWARFIndex.h"
#include "UniqueDWARFASTType.h"
+class DWARFASTParserClang;
+
+namespace llvm {
+class DWARFDebugAbbrev;
+} // namespace llvm
+
+namespace lldb_private::plugin {
+namespace dwarf {
// Forward Declarations for this DWARF plugin
class DebugMapModule;
class DWARFCompileUnit;
-class DWARFDebugAbbrev;
class DWARFDebugAranges;
class DWARFDebugInfo;
class DWARFDebugInfoEntry;
@@ -53,11 +61,10 @@ class DWARFTypeUnit;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARFDwo;
class SymbolFileDWARFDwp;
-class UserID;
#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
-class SymbolFileDWARF : public lldb_private::SymbolFileCommon {
+class SymbolFileDWARF : public SymbolFileCommon {
/// LLVM RTTI support.
static char ID;
@@ -75,26 +82,24 @@ public:
friend class DebugMapModule;
friend class DWARFCompileUnit;
friend class DWARFDIE;
- friend class DWARFASTParserClang;
+ friend class DWARFASTParser;
// Static Functions
static void Initialize();
static void Terminate();
- static void DebuggerInitialize(lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(Debugger &debugger);
static llvm::StringRef GetPluginNameStatic() { return "dwarf"; }
static llvm::StringRef GetPluginDescriptionStatic();
- static lldb_private::SymbolFile *
- CreateInstance(lldb::ObjectFileSP objfile_sp);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFileDWARF(lldb::ObjectFileSP objfile_sp,
- lldb_private::SectionList *dwo_section_list);
+ SymbolFileDWARF(lldb::ObjectFileSP objfile_sp, SectionList *dwo_section_list);
~SymbolFileDWARF() override;
@@ -104,118 +109,95 @@ public:
// Compile Unit function calls
- lldb::LanguageType
- ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
+ lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override;
- lldb_private::XcodeSDK
- ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+ XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) override;
- size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
+ size_t ParseFunctions(CompileUnit &comp_unit) override;
- bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
+ bool ParseLineTable(CompileUnit &comp_unit) override;
- bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+ bool ParseDebugMacros(CompileUnit &comp_unit) override;
- bool ForEachExternalModule(
- lldb_private::CompileUnit &, llvm::DenseSet<lldb_private::SymbolFile *> &,
- llvm::function_ref<bool(lldb_private::Module &)>) override;
+ bool ForEachExternalModule(CompileUnit &, llvm::DenseSet<SymbolFile *> &,
+ llvm::function_ref<bool(Module &)>) override;
- bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
- lldb_private::FileSpecList &support_files) override;
+ bool ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) override;
- bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
+ bool ParseIsOptimized(CompileUnit &comp_unit) override;
- size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
+ size_t ParseTypes(CompileUnit &comp_unit) override;
- bool ParseImportedModules(
- const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::SourceModule> &imported_modules) override;
+ bool
+ ParseImportedModules(const SymbolContext &sc,
+ std::vector<SourceModule> &imported_modules) override;
- size_t ParseBlocksRecursive(lldb_private::Function &func) override;
+ size_t ParseBlocksRecursive(Function &func) override;
- size_t
- ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+ size_t ParseVariablesForContext(const SymbolContext &sc) override;
- lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- std::optional<ArrayInfo> GetDynamicArrayInfoForUID(
- lldb::user_id_t type_uid,
- const lldb_private::ExecutionContext *exe_ctx) override;
+ std::optional<ArrayInfo>
+ GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,
+ const ExecutionContext *exe_ctx) override;
- bool CompleteType(lldb_private::CompilerType &compiler_type) override;
+ bool CompleteType(CompilerType &compiler_type) override;
- lldb_private::Type *ResolveType(const DWARFDIE &die,
- bool assert_not_being_parsed = true,
- bool resolve_function_context = false);
+ Type *ResolveType(const DWARFDIE &die, bool assert_not_being_parsed = true,
+ bool resolve_function_context = false);
- lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
+ CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUID(lldb::user_id_t uid) override;
+ CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUID(lldb::user_id_t uid) override;
+ CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override;
- void
- ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+ std::vector<CompilerContext>
+ GetCompilerContextForUID(lldb::user_id_t uid) override;
- uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
- lldb::SymbolContextItem resolve_scope,
- lldb_private::SymbolContext &sc) override;
+ void ParseDeclsForContext(CompilerDeclContext decl_ctx) override;
- lldb_private::Status
- CalculateFrameVariableError(lldb_private::StackFrame &frame) override;
+ uint32_t ResolveSymbolContext(const Address &so_addr,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContext &sc) override;
- uint32_t ResolveSymbolContext(
- const lldb_private::SourceLocationSpec &src_location_spec,
- lldb::SymbolContextItem resolve_scope,
- lldb_private::SymbolContextList &sc_list) override;
+ Status CalculateFrameVariableError(StackFrame &frame) override;
- void
- FindGlobalVariables(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContextList &sc_list) override;
- void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ VariableList &variables) override;
- void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- bool include_inlines,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindGlobalVariables(const RegularExpression &regex, uint32_t max_matches,
+ VariableList &variables) override;
- void FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const Module::LookupInfo &lookup_info,
+ const CompilerDeclContext &parent_decl_ctx,
+ bool include_inlines, SymbolContextList &sc_list) override;
- void GetMangledNamesForFunction(
- const std::string &scope_qualified_name,
- std::vector<lldb_private::ConstString> &mangled_names) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
void
- FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
+ GetMangledNamesForFunction(const std::string &scope_qualified_name,
+ std::vector<ConstString> &mangled_names) override;
- void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
- lldb_private::LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
- void GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override;
llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
- lldb_private::CompilerDeclContext
- FindNamespace(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- bool only_root_namespaces) override;
+ CompilerDeclContext FindNamespace(ConstString name,
+ const CompilerDeclContext &parent_decl_ctx,
+ bool only_root_namespaces) override;
void PreloadSymbols() override;
@@ -224,7 +206,7 @@ public:
// PluginInterface protocol
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
- DWARFDebugAbbrev *DebugAbbrev();
+ llvm::DWARFDebugAbbrev *DebugAbbrev();
DWARFDebugInfo &DebugInfo();
@@ -235,25 +217,22 @@ public:
DWARFDIE
GetDeclContextDIEContainingDIE(const DWARFDIE &die);
- bool
- HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type);
+ bool HasForwardDeclForCompilerType(const CompilerType &compiler_type);
- lldb_private::CompileUnit *
- GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu);
+ CompileUnit *GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu);
- virtual void GetObjCMethods(lldb_private::ConstString class_name,
+ virtual void GetObjCMethods(ConstString class_name,
llvm::function_ref<bool(DWARFDIE die)> callback);
bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu);
- lldb_private::DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset);
+ DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset);
static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
- lldb::ModuleSP GetExternalModule(lldb_private::ConstString name);
+ lldb::ModuleSP GetExternalModule(ConstString name);
- typedef std::map<lldb_private::ConstString, lldb::ModuleSP>
- ExternalTypeModuleMap;
+ typedef std::map<ConstString, lldb::ModuleSP> ExternalTypeModuleMap;
/// Return the list of Clang modules imported by this SymbolFile.
const ExternalTypeModuleMap &getExternalTypeModules() const {
@@ -271,22 +250,26 @@ public:
/// If this is a DWARF object with a single CU, return its DW_AT_dwo_id.
std::optional<uint64_t> GetDWOId();
- static bool
- DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx,
- const DWARFDIE &die, bool only_root_namespaces = false);
+ static bool DIEInDeclContext(const CompilerDeclContext &parent_decl_ctx,
+ const DWARFDIE &die,
+ bool only_root_namespaces = false);
- std::vector<std::unique_ptr<lldb_private::CallEdge>>
- ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
+ std::vector<std::unique_ptr<CallEdge>>
+ ParseCallEdgesInFunction(UserID func_id) override;
- void Dump(lldb_private::Stream &s) override;
+ void Dump(Stream &s) override;
- void DumpClangAST(lldb_private::Stream &s) override;
+ void DumpClangAST(Stream &s) override;
- lldb_private::DWARFContext &GetDWARFContext() { return m_context; }
+ /// List separate dwo files.
+ bool GetSeparateDebugInfo(StructuredData::Dictionary &d,
+ bool errors_only) override;
+
+ DWARFContext &GetDWARFContext() { return m_context; }
const std::shared_ptr<SymbolFileDWARFDwo> &GetDwpSymbolFile();
- lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
+ FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
static llvm::Expected<lldb::TypeSystemSP> GetTypeSystem(DWARFUnit &unit);
@@ -294,12 +277,11 @@ public:
// CompilerDecl related functions
- static lldb_private::CompilerDecl GetDecl(const DWARFDIE &die);
+ static CompilerDecl GetDecl(const DWARFDIE &die);
- static lldb_private::CompilerDeclContext GetDeclContext(const DWARFDIE &die);
+ static CompilerDeclContext GetDeclContext(const DWARFDIE &die);
- static lldb_private::CompilerDeclContext
- GetContainingDeclContext(const DWARFDIE &die);
+ static CompilerDeclContext GetContainingDeclContext(const DWARFDIE &die);
static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die);
@@ -309,142 +291,152 @@ public:
/// Same as GetLanguage() but reports all C++ versions as C++ (no version).
static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit);
- lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override {
+ StatsDuration::Duration GetDebugInfoParseTime() override {
return m_parse_time;
}
- lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;
+ StatsDuration::Duration GetDebugInfoIndexTime() override;
- lldb_private::StatsDuration &GetDebugInfoParseTimeRef() {
- return m_parse_time;
- }
+ StatsDuration &GetDebugInfoParseTimeRef() { return m_parse_time; }
virtual lldb::offset_t
- GetVendorDWARFOpcodeSize(const lldb_private::DataExtractor &data,
+ GetVendorDWARFOpcodeSize(const DataExtractor &data,
const lldb::offset_t data_offset,
const uint8_t op) const {
return LLDB_INVALID_OFFSET;
}
- virtual bool
- ParseVendorDWARFOpcode(uint8_t op, const lldb_private::DataExtractor &opcodes,
- lldb::offset_t &offset,
- std::vector<lldb_private::Value> &stack) const {
+ virtual bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+ lldb::offset_t &offset,
+ std::vector<Value> &stack) const {
return false;
}
- lldb_private::ConstString ConstructFunctionDemangledName(const DWARFDIE &die);
+ ConstString ConstructFunctionDemangledName(const DWARFDIE &die);
std::optional<uint64_t> GetFileIndex() const { return m_file_index; }
void SetFileIndex(std::optional<uint64_t> file_index) {
m_file_index = file_index;
}
-protected:
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
- DIEToTypePtr;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
- DIEToVariableSP;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> DIEToTypePtr;
+
+ virtual DIEToTypePtr &GetDIEToType() { return m_die_to_type; }
+
typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
lldb::opaque_compiler_type_t>
- DIEToClangType;
- typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
+ DIEToCompilerType;
+
+ virtual DIEToCompilerType &GetForwardDeclDIEToCompilerType() {
+ return m_forward_decl_die_to_compiler_type;
+ }
+
+ typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef>
+ CompilerTypeToDIE;
+
+ virtual CompilerTypeToDIE &GetForwardDeclCompilerTypeToDIE() {
+ return m_forward_decl_compiler_type_to_die;
+ }
+
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
+ DIEToVariableSP;
+
+ virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; }
+
+ virtual UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap();
+
+ bool ClassOrStructIsVirtual(const DWARFDIE &die);
+ SymbolFileDWARFDebugMap *GetDebugMapSymfile();
+
+ virtual lldb::TypeSP
+ FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die);
+
+ virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, ConstString type_name, bool must_be_implementation);
+
+ Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+
+ Type *ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed);
+
+ Type *ResolveTypeUID(const DIERef &die_ref);
+
+protected:
SymbolFileDWARF(const SymbolFileDWARF &) = delete;
const SymbolFileDWARF &operator=(const SymbolFileDWARF &) = delete;
virtual void LoadSectionData(lldb::SectionType sect_type,
- lldb_private::DWARFDataExtractor &data);
+ DWARFDataExtractor &data);
- bool DeclContextMatchesThisSymbolFile(
- const lldb_private::CompilerDeclContext &decl_ctx);
+ bool DeclContextMatchesThisSymbolFile(const CompilerDeclContext &decl_ctx);
uint32_t CalculateNumCompileUnits() override;
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- lldb_private::TypeList &GetTypeList() override;
+ TypeList &GetTypeList() override;
lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu);
- virtual DWARFCompileUnit *
- GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
+ virtual DWARFCompileUnit *GetDWARFCompileUnit(CompileUnit *comp_unit);
DWARFUnit *GetNextUnparsedDWARFCompileUnit(DWARFUnit *prev_cu);
- bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc);
+ bool GetFunction(const DWARFDIE &die, SymbolContext &sc);
- lldb_private::Function *ParseFunction(lldb_private::CompileUnit &comp_unit,
- const DWARFDIE &die);
+ Function *ParseFunction(CompileUnit &comp_unit, const DWARFDIE &die);
- size_t ParseBlocksRecursive(lldb_private::CompileUnit &comp_unit,
- lldb_private::Block *parent_block,
+ size_t ParseBlocksRecursive(CompileUnit &comp_unit, Block *parent_block,
const DWARFDIE &die,
lldb::addr_t subprogram_low_pc, uint32_t depth);
- size_t ParseTypes(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ size_t ParseTypes(const SymbolContext &sc, const DWARFDIE &die,
bool parse_siblings, bool parse_children);
- lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, bool *type_is_new);
+ lldb::TypeSP ParseType(const SymbolContext &sc, const DWARFDIE &die,
+ bool *type_is_new);
bool ParseSupportFiles(DWARFUnit &dwarf_cu, const lldb::ModuleSP &module,
- lldb_private::FileSpecList &support_files);
-
- lldb_private::Type *ResolveTypeUID(const DWARFDIE &die,
- bool assert_not_being_parsed);
-
- lldb_private::Type *ResolveTypeUID(const DIERef &die_ref);
+ FileSpecList &support_files);
- lldb::VariableSP ParseVariableDIE(const lldb_private::SymbolContext &sc,
+ lldb::VariableSP ParseVariableDIE(const SymbolContext &sc,
const DWARFDIE &die,
const lldb::addr_t func_low_pc);
- lldb::VariableSP ParseVariableDIECached(const lldb_private::SymbolContext &sc,
+ lldb::VariableSP ParseVariableDIECached(const SymbolContext &sc,
const DWARFDIE &die);
- void
- ParseAndAppendGlobalVariable(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- lldb_private::VariableList &cc_variable_list);
+ void ParseAndAppendGlobalVariable(const SymbolContext &sc,
+ const DWARFDIE &die,
+ VariableList &cc_variable_list);
- size_t ParseVariablesInFunctionContext(const lldb_private::SymbolContext &sc,
+ size_t ParseVariablesInFunctionContext(const SymbolContext &sc,
const DWARFDIE &die,
const lldb::addr_t func_low_pc);
- size_t ParseVariablesInFunctionContextRecursive(
- const lldb_private::SymbolContext &sc, const DWARFDIE &die,
- lldb::addr_t func_low_pc, DIEArray &accumulator);
+ size_t ParseVariablesInFunctionContextRecursive(const SymbolContext &sc,
+ const DWARFDIE &die,
+ lldb::addr_t func_low_pc,
+ DIEArray &accumulator);
- size_t PopulateBlockVariableList(lldb_private::VariableList &variable_list,
- const lldb_private::SymbolContext &sc,
+ size_t PopulateBlockVariableList(VariableList &variable_list,
+ const SymbolContext &sc,
llvm::ArrayRef<DIERef> variable_dies,
lldb::addr_t func_low_pc);
DIEArray MergeBlockAbstractParameters(const DWARFDIE &block_die,
DIEArray &&variable_dies);
- bool ClassOrStructIsVirtual(const DWARFDIE &die);
-
// Given a die_offset, figure out the symbol context representing that die.
bool ResolveFunction(const DWARFDIE &die, bool include_inlines,
- lldb_private::SymbolContextList &sc_list);
+ SymbolContextList &sc_list);
/// Resolve functions and (possibly) blocks for the given file address and a
/// compile unit. The compile unit comes from the sc argument and it must be
/// set. The results of the lookup (if any) are written back to the symbol
/// context.
void ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, bool lookup_block,
- lldb_private::SymbolContext &sc);
+ SymbolContext &sc);
- virtual lldb::TypeSP
- FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die);
-
- virtual lldb::TypeSP
- FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die,
- lldb_private::ConstString type_name,
- bool must_be_implementation);
-
- lldb_private::Symbol *
- GetObjCClassSymbol(lldb_private::ConstString objc_class_name);
+ Symbol *GetObjCClassSymbol(ConstString objc_class_name);
lldb::TypeSP GetTypeForDIE(const DWARFDIE &die,
bool resolve_function_context = false);
@@ -453,8 +445,6 @@ protected:
m_debug_map_module_wp = module_sp;
}
- SymbolFileDWARFDebugMap *GetDebugMapSymfile();
-
DWARFDIE
FindBlockContainingSpecification(const DIERef &func_die_ref,
dw_offset_t spec_block_die_offset);
@@ -463,16 +453,13 @@ protected:
FindBlockContainingSpecification(const DWARFDIE &die,
dw_offset_t spec_block_die_offset);
- virtual UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap();
-
bool DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2);
- bool ClassContainsSelector(const DWARFDIE &class_die,
- lldb_private::ConstString selector);
+ bool ClassContainsSelector(const DWARFDIE &class_die, ConstString selector);
/// Parse call site entries (DW_TAG_call_site), including any nested call site
/// parameters (DW_TAG_call_site_parameter).
- std::vector<std::unique_ptr<lldb_private::CallEdge>>
+ std::vector<std::unique_ptr<CallEdge>>
CollectCallEdges(lldb::ModuleSP module, DWARFDIE function_die);
/// If this symbol file is linked to by a debug map (see
@@ -482,48 +469,34 @@ protected:
/// needed, on success and LLDB_INVALID_ADDRESS otherwise.
lldb::addr_t FixupAddress(lldb::addr_t file_addr);
- bool FixupAddress(lldb_private::Address &addr);
+ bool FixupAddress(Address &addr);
- typedef llvm::SetVector<lldb_private::Type *> TypeSet;
+ typedef llvm::SetVector<Type *> TypeSet;
void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
dw_offset_t max_die_offset, uint32_t type_mask,
TypeSet &type_set);
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
- lldb_private::Variable *>
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, Variable *>
GlobalVariableMap;
GlobalVariableMap &GetGlobalAranges();
void UpdateExternalModuleListIfNeeded();
- virtual DIEToTypePtr &GetDIEToType() { return m_die_to_type; }
-
- virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; }
-
- virtual DIEToClangType &GetForwardDeclDieToClangType() {
- return m_forward_decl_die_to_clang_type;
- }
-
- virtual ClangTypeToDIE &GetForwardDeclClangTypeToDie() {
- return m_forward_decl_clang_type_to_die;
- }
-
void BuildCuTranslationTable();
std::optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx);
void FindDwpSymbolFile();
- const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
+ const FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
- void InitializeFirstCodeAddressRecursive(
- const lldb_private::SectionList &section_list);
+ void InitializeFirstCodeAddressRecursive(const SectionList &section_list);
void InitializeFirstCodeAddress();
- void GetCompileOptions(
- std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) override;
+ void
+ GetCompileOptions(std::unordered_map<lldb::CompUnitSP, Args> &args) override;
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap *m_debug_map_symfile;
@@ -531,22 +504,21 @@ protected:
llvm::once_flag m_dwp_symfile_once_flag;
std::shared_ptr<SymbolFileDWARFDwo> m_dwp_symfile;
- lldb_private::DWARFContext m_context;
+ DWARFContext m_context;
llvm::once_flag m_info_once_flag;
std::unique_ptr<DWARFDebugInfo> m_info;
- std::unique_ptr<DWARFDebugAbbrev> m_abbr;
+ std::unique_ptr<llvm::DWARFDebugAbbrev> m_abbr;
std::unique_ptr<GlobalVariableMap> m_global_aranges_up;
- typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
- DebugMacrosMap;
+ typedef std::unordered_map<lldb::offset_t, DebugMacrosSP> DebugMacrosMap;
DebugMacrosMap m_debug_macros_map;
ExternalTypeModuleMap m_external_type_modules;
- std::unique_ptr<lldb_private::DWARFIndex> m_index;
+ std::unique_ptr<DWARFIndex> m_index;
bool m_fetched_external_modules : 1;
- lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+ LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
typedef std::set<DIERef> DIERefSet;
typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
@@ -555,10 +527,9 @@ protected:
UniqueDWARFASTTypeMap m_unique_ast_type_map;
DIEToTypePtr m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
- DIEToClangType m_forward_decl_die_to_clang_type;
- ClangTypeToDIE m_forward_decl_clang_type_to_die;
- llvm::DenseMap<dw_offset_t, lldb_private::FileSpecList>
- m_type_unit_support_files;
+ DIEToCompilerType m_forward_decl_die_to_compiler_type;
+ CompilerTypeToDIE m_forward_decl_compiler_type_to_die;
+ llvm::DenseMap<dw_offset_t, FileSpecList> m_type_unit_support_files;
std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
/// DWARF does not provide a good way for traditional (concatenating) linkers
/// to invalidate debug info describing dead-stripped code. These linkers will
@@ -567,7 +538,7 @@ protected:
/// Try to filter out this debug info by comparing it to the lowest code
/// address in the module.
lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS;
- lldb_private::StatsDuration m_parse_time;
+ StatsDuration m_parse_time;
std::atomic_flag m_dwo_warning_issued = ATOMIC_FLAG_INIT;
/// If this DWARF file a .DWO file or a DWARF .o file on mac when
/// no dSYM file is being used, this file index will be set to a
@@ -575,5 +546,7 @@ protected:
/// an index that identifies the .DWO or .o file.
std::optional<uint64_t> m_file_index;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
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 bb66fbadfb64..e5b59460cb85 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -18,13 +18,11 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/Utility/RegularExpression.h"
-#include "lldb/Utility/Timer.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/Utility/Timer.h"
//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
-#if defined(DEBUG_OSO_DMAP)
-#include "lldb/Core/StreamFile.h"
-#endif
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
@@ -45,6 +43,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
char SymbolFileDWARFDebugMap::ID;
@@ -169,11 +168,13 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
return file_range_map;
}
+namespace lldb_private::plugin {
+namespace dwarf {
class DebugMapModule : public Module {
public:
DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
const FileSpec &file_spec, const ArchSpec &arch,
- const ConstString *object_name, off_t object_offset,
+ ConstString object_name, off_t object_offset,
const llvm::sys::TimePoint<> object_mod_time)
: Module(file_spec, arch, object_name, object_offset, object_mod_time),
m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {}
@@ -225,6 +226,8 @@ protected:
ModuleWP m_exe_module_wp;
const uint32_t m_cu_idx;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
void SymbolFileDWARFDebugMap::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
@@ -462,7 +465,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
.c_str());
comp_unit_info->oso_sp->module_sp = std::make_shared<DebugMapModule>(
obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
- oso_arch, oso_object ? &oso_object : nullptr, 0,
+ oso_arch, oso_object, 0,
oso_object ? comp_unit_info->oso_mod_time : llvm::sys::TimePoint<>());
if (oso_object && !comp_unit_info->oso_sp->module_sp->GetObjectFile() &&
@@ -800,7 +803,7 @@ bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
bool success = false;
if (compiler_type) {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) {
+ if (oso_dwarf->HasForwardDeclForCompilerType(compiler_type)) {
oso_dwarf->CompleteType(compiler_type);
success = true;
return true;
@@ -1224,27 +1227,12 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
return TypeSP();
}
-void SymbolFileDWARFDebugMap::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
+void SymbolFileDWARFDebugMap::FindTypes(const TypeQuery &query,
+ TypeResults &results) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(name, parent_decl_ctx, max_matches,
- searched_symbol_files, types);
- return types.GetSize() >= max_matches;
- });
-}
-
-void SymbolFileDWARFDebugMap::FindTypes(
- llvm::ArrayRef<CompilerContext> context, LanguageSet languages,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- LLDB_SCOPED_TIMER();
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(context, languages, searched_symbol_files, types);
- return false;
+ oso_dwarf->FindTypes(query, results);
+ return !results.Done(query); // Keep iterating if we aren't done.
});
}
@@ -1274,6 +1262,43 @@ void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
});
}
+bool SymbolFileDWARFDebugMap::GetSeparateDebugInfo(
+ lldb_private::StructuredData::Dictionary &d, bool errors_only) {
+ StructuredData::Array separate_debug_info_files;
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
+ const auto &info = m_compile_unit_infos[cu_idx];
+ StructuredData::DictionarySP oso_data =
+ std::make_shared<StructuredData::Dictionary>();
+ oso_data->AddStringItem("so_file", info.so_file.GetPath());
+ oso_data->AddStringItem("oso_path", info.oso_path);
+ oso_data->AddIntegerItem("oso_mod_time",
+ (uint32_t)llvm::sys::toTimeT(info.oso_mod_time));
+
+ bool loaded_successfully = false;
+ if (GetModuleByOSOIndex(cu_idx)) {
+ // If we have a valid pointer to the module, we successfully
+ // loaded the oso if there are no load errors.
+ if (!info.oso_load_error.Fail()) {
+ loaded_successfully = true;
+ }
+ }
+ if (!loaded_successfully) {
+ oso_data->AddStringItem("error", info.oso_load_error.AsCString());
+ }
+ oso_data->AddBooleanItem("loaded", loaded_successfully);
+ if (!errors_only || oso_data->HasKey("error"))
+ separate_debug_info_files.AddItem(oso_data);
+ }
+
+ d.AddStringItem("type", "oso");
+ d.AddStringItem("symfile", GetMainObjectFile()->GetFileSpec().GetPath());
+ d.AddItem("separate-debug-info-files",
+ std::make_shared<StructuredData::Array>(
+ std::move(separate_debug_info_files)));
+ return true;
+}
+
lldb::CompUnitSP
SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf, DWARFCompileUnit &dwarf_cu) {
if (oso_dwarf) {
@@ -1340,19 +1365,25 @@ void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
CompilerDeclContext
SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) {
const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
- if (oso_dwarf)
+ if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx))
return oso_dwarf->GetDeclContextForUID(type_uid);
- return CompilerDeclContext();
+ return {};
}
CompilerDeclContext
SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
- if (oso_dwarf)
+ if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx))
return oso_dwarf->GetDeclContextContainingUID(type_uid);
- return CompilerDeclContext();
+ return {};
+}
+
+std::vector<CompilerContext>
+SymbolFileDWARFDebugMap::GetCompilerContextForUID(lldb::user_id_t type_uid) {
+ const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
+ if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx))
+ return oso_dwarf->GetCompilerContextForUID(type_uid);
+ return {};
}
void SymbolFileDWARFDebugMap::ParseDeclsForContext(
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 881fd4c45ff0..cd0a4bb6e41c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -19,13 +19,18 @@
#include <vector>
#include "UniqueDWARFASTType.h"
+#include "lldb/Utility/StructuredData.h"
+class DWARFASTParserClang;
+
+namespace lldb_private::plugin {
+namespace dwarf {
class SymbolFileDWARF;
class DWARFCompileUnit;
class DWARFDebugAranges;
class DWARFDeclContext;
-class SymbolFileDWARFDebugMap : public lldb_private::SymbolFileCommon {
+class SymbolFileDWARFDebugMap : public SymbolFileCommon {
/// LLVM RTTI support.
static char ID;
@@ -47,8 +52,7 @@ public:
static llvm::StringRef GetPluginDescriptionStatic();
- static lldb_private::SymbolFile *
- CreateInstance(lldb::ObjectFileSP objfile_sp);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
SymbolFileDWARFDebugMap(lldb::ObjectFileSP objfile_sp);
@@ -58,110 +62,92 @@ public:
void InitializeObject() override;
// Compile Unit function calls
- lldb::LanguageType
- ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
- lldb_private::XcodeSDK
- ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+ lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override;
+ XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) override;
llvm::SmallSet<lldb::LanguageType, 4>
- ParseAllLanguages(lldb_private::CompileUnit &comp_unit) override;
- size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
- bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
- bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
-
- bool ForEachExternalModule(
- lldb_private::CompileUnit &, llvm::DenseSet<lldb_private::SymbolFile *> &,
- llvm::function_ref<bool(lldb_private::Module &)>) override;
-
- bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
- lldb_private::FileSpecList &support_files) override;
-
- bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
-
- size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
-
- bool ParseImportedModules(
- const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::SourceModule> &imported_modules) override;
- size_t ParseBlocksRecursive(lldb_private::Function &func) override;
- size_t
- ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
-
- lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- std::optional<ArrayInfo> GetDynamicArrayInfoForUID(
- lldb::user_id_t type_uid,
- const lldb_private::ExecutionContext *exe_ctx) override;
-
- lldb_private::CompilerDeclContext
- GetDeclContextForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUID(lldb::user_id_t uid) override;
- void
- ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+ ParseAllLanguages(CompileUnit &comp_unit) override;
+ size_t ParseFunctions(CompileUnit &comp_unit) override;
+ bool ParseLineTable(CompileUnit &comp_unit) override;
+ bool ParseDebugMacros(CompileUnit &comp_unit) override;
+
+ bool ForEachExternalModule(CompileUnit &, llvm::DenseSet<SymbolFile *> &,
+ llvm::function_ref<bool(Module &)>) override;
+
+ bool ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) override;
+
+ bool ParseIsOptimized(CompileUnit &comp_unit) override;
+
+ size_t ParseTypes(CompileUnit &comp_unit) override;
+
+ bool
+ ParseImportedModules(const SymbolContext &sc,
+ std::vector<SourceModule> &imported_modules) override;
+ size_t ParseBlocksRecursive(Function &func) override;
+ size_t ParseVariablesForContext(const SymbolContext &sc) override;
+
+ Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ std::optional<ArrayInfo>
+ GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,
+ const ExecutionContext *exe_ctx) override;
- bool CompleteType(lldb_private::CompilerType &compiler_type) override;
- uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override;
+ CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override;
+ std::vector<CompilerContext>
+ GetCompilerContextForUID(lldb::user_id_t uid) override;
+ void ParseDeclsForContext(CompilerDeclContext decl_ctx) override;
+
+ bool CompleteType(CompilerType &compiler_type) override;
+ uint32_t ResolveSymbolContext(const Address &so_addr,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContext &sc) override;
+ uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
lldb::SymbolContextItem resolve_scope,
- lldb_private::SymbolContext &sc) override;
- uint32_t ResolveSymbolContext(
- const lldb_private::SourceLocationSpec &src_location_spec,
- lldb::SymbolContextItem resolve_scope,
- lldb_private::SymbolContextList &sc_list) override;
+ SymbolContextList &sc_list) override;
- lldb_private::Status
- CalculateFrameVariableError(lldb_private::StackFrame &frame) override;
+ Status CalculateFrameVariableError(StackFrame &frame) override;
- void
- FindGlobalVariables(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
- void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
- lldb_private::VariableList &variables) override;
- void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- bool include_inlines,
- lldb_private::SymbolContextList &sc_list) override;
- void FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines,
- lldb_private::SymbolContextList &sc_list) override;
- void
- FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
- void
- FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> context,
- lldb_private::LanguageSet languages,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
- lldb_private::CompilerDeclContext
- FindNamespace(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- bool only_root_namespaces) override;
- void GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
- std::vector<std::unique_ptr<lldb_private::CallEdge>>
- ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
-
- void DumpClangAST(lldb_private::Stream &s) override;
+ VariableList &variables) override;
+ void FindGlobalVariables(const RegularExpression &regex, uint32_t max_matches,
+ VariableList &variables) override;
+ void FindFunctions(const Module::LookupInfo &lookup_info,
+ const CompilerDeclContext &parent_decl_ctx,
+ bool include_inlines, SymbolContextList &sc_list) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
+ CompilerDeclContext FindNamespace(ConstString name,
+ const CompilerDeclContext &parent_decl_ctx,
+ bool only_root_namespaces) override;
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override;
+ std::vector<std::unique_ptr<CallEdge>>
+ ParseCallEdgesInFunction(UserID func_id) override;
+
+ void DumpClangAST(Stream &s) override;
+
+ /// List separate oso files.
+ bool GetSeparateDebugInfo(StructuredData::Dictionary &d,
+ bool errors_only) override;
// PluginInterface protocol
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
// Statistics overrides.
- lldb_private::ModuleList GetDebugInfoModules() override;
+ ModuleList GetDebugInfoModules() override;
- void GetCompileOptions(
- std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) override;
+ void
+ GetCompileOptions(std::unordered_map<lldb::CompUnitSP, Args> &args) override;
protected:
enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
friend class DebugMapModule;
- friend class DWARFASTParserClang;
+ friend class ::DWARFASTParserClang;
friend class DWARFCompileUnit;
friend class SymbolFileDWARF;
struct OSOInfo {
@@ -172,16 +158,15 @@ protected:
typedef std::shared_ptr<OSOInfo> OSOInfoSP;
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
- lldb::addr_t>
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t>
FileRangeMap;
// Class specific types
struct CompileUnitInfo {
- lldb_private::FileSpec so_file;
- lldb_private::ConstString oso_path;
+ FileSpec so_file;
+ ConstString oso_path;
llvm::sys::TimePoint<> oso_mod_time;
- lldb_private::Status oso_load_error;
+ Status oso_load_error;
OSOInfoSP oso_sp;
/// The compile units that an object file contains.
llvm::SmallVector<lldb::CompUnitSP, 2> compile_units_sps;
@@ -223,28 +208,26 @@ protected:
static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file);
- bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec);
+ bool GetFileSpecForSO(uint32_t oso_idx, FileSpec &file_spec);
- CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc);
- CompileUnitInfo *GetCompUnitInfo(const lldb_private::CompileUnit &comp_unit);
+ CompileUnitInfo *GetCompUnitInfo(const SymbolContext &sc);
+ CompileUnitInfo *GetCompUnitInfo(const CompileUnit &comp_unit);
- size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module,
+ size_t GetCompUnitInfosForModule(const Module *oso_module,
std::vector<CompileUnitInfo *> &cu_infos);
- lldb_private::Module *
- GetModuleByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+ Module *GetModuleByCompUnitInfo(CompileUnitInfo *comp_unit_info);
- lldb_private::Module *GetModuleByOSOIndex(uint32_t oso_idx);
+ Module *GetModuleByOSOIndex(uint32_t oso_idx);
- lldb_private::ObjectFile *
- GetObjectFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+ ObjectFile *GetObjectFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
- lldb_private::ObjectFile *GetObjectFileByOSOIndex(uint32_t oso_idx);
+ ObjectFile *GetObjectFileByOSOIndex(uint32_t oso_idx);
uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info);
- SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc);
- SymbolFileDWARF *GetSymbolFile(const lldb_private::CompileUnit &comp_unit);
+ SymbolFileDWARF *GetSymbolFile(const SymbolContext &sc);
+ SymbolFileDWARF *GetSymbolFile(const CompileUnit &comp_unit);
SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
@@ -275,11 +258,11 @@ protected:
static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
const CompileUnitInfo *comp_unit_info);
- void PrivateFindGlobalVariables(
- lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
- lldb_private::VariableList &variables);
+ void
+ PrivateFindGlobalVariables(ConstString name,
+ const CompilerDeclContext &parent_decl_ctx,
+ const std::vector<uint32_t> &name_symbol_indexes,
+ uint32_t max_matches, VariableList &variables);
void SetCompileUnit(SymbolFileDWARF *oso_dwarf,
const lldb::CompUnitSP &cu_sp);
@@ -297,8 +280,7 @@ protected:
bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);
lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, lldb_private::ConstString type_name,
- bool must_be_implementation);
+ const DWARFDIE &die, ConstString type_name, bool must_be_implementation);
UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() {
return m_unique_ast_type_map;
@@ -329,19 +311,16 @@ protected:
lldb::addr_t m_oso_file_addr = LLDB_INVALID_ADDRESS;
};
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry>
- DebugMap;
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
// Member Variables
std::bitset<kNumFlags> m_flags;
std::vector<CompileUnitInfo> m_compile_unit_infos;
std::vector<uint32_t> m_func_indexes; // Sorted by address
std::vector<uint32_t> m_glob_indexes;
- std::map<std::pair<lldb_private::ConstString, llvm::sys::TimePoint<>>,
- OSOInfoSP>
- m_oso_map;
+ std::map<std::pair<ConstString, llvm::sys::TimePoint<>>, OSOInfoSP> m_oso_map;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
- lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+ LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
DebugMap m_debug_map;
// When an object file from the debug map gets parsed in
@@ -365,7 +344,7 @@ protected:
/// \return
/// Returns true if \a addr was converted to be an executable
/// section/offset address, false otherwise.
- bool LinkOSOAddress(lldb_private::Address &addr);
+ bool LinkOSOAddress(Address &addr);
/// Convert a .o file "file address" to an executable "file address".
///
@@ -396,12 +375,13 @@ protected:
/// Returns a valid line table full of linked addresses, or NULL
/// if none of the line table addresses exist in the main
/// executable.
- lldb_private::LineTable *
- LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
- lldb_private::LineTable *line_table);
+ LineTable *LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
+ LineTable *line_table);
size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data,
DWARFDebugAranges *debug_aranges);
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 78c3c19684e1..ca698a84a914 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -21,6 +21,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
char SymbolFileDWARFDwo::ID;
@@ -98,14 +99,14 @@ SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
return GetBaseSymbolFile().GetDIEToVariable();
}
-SymbolFileDWARF::DIEToClangType &
-SymbolFileDWARFDwo::GetForwardDeclDieToClangType() {
- return GetBaseSymbolFile().GetForwardDeclDieToClangType();
+SymbolFileDWARF::DIEToCompilerType &
+SymbolFileDWARFDwo::GetForwardDeclDIEToCompilerType() {
+ return GetBaseSymbolFile().GetForwardDeclDIEToCompilerType();
}
-SymbolFileDWARF::ClangTypeToDIE &
-SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
- return GetBaseSymbolFile().GetForwardDeclClangTypeToDie();
+SymbolFileDWARF::CompilerTypeToDIE &
+SymbolFileDWARFDwo::GetForwardDeclCompilerTypeToDIE() {
+ return GetBaseSymbolFile().GetForwardDeclCompilerTypeToDIE();
}
void SymbolFileDWARFDwo::GetObjCMethods(
@@ -141,3 +142,10 @@ SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
return DebugInfo().GetDIE(die_ref);
return GetBaseSymbolFile().GetDIE(die_ref);
}
+
+void SymbolFileDWARFDwo::FindGlobalVariables(
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
+ uint32_t max_matches, VariableList &variables) {
+ GetBaseSymbolFile().FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index e98ea49d939b..9f5950e51b0c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -12,6 +12,8 @@
#include "SymbolFileDWARF.h"
#include <optional>
+namespace lldb_private::plugin {
+namespace dwarf {
class SymbolFileDWARFDwo : public SymbolFileDWARF {
/// LLVM RTTI support.
static char ID;
@@ -32,7 +34,7 @@ public:
DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash);
- void GetObjCMethods(lldb_private::ConstString class_name,
+ void GetObjCMethods(ConstString class_name,
llvm::function_ref<bool(DWARFDIE die)> callback) override;
llvm::Expected<lldb::TypeSystemSP>
@@ -41,33 +43,37 @@ public:
DWARFDIE
GetDIE(const DIERef &die_ref) override;
- lldb::offset_t
- GetVendorDWARFOpcodeSize(const lldb_private::DataExtractor &data,
- const lldb::offset_t data_offset,
- const uint8_t op) const override;
+ lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data,
+ const lldb::offset_t data_offset,
+ const uint8_t op) const override;
- bool ParseVendorDWARFOpcode(
- uint8_t op, const lldb_private::DataExtractor &opcodes,
- lldb::offset_t &offset,
- std::vector<lldb_private::Value> &stack) const override;
+ bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+ lldb::offset_t &offset,
+ std::vector<Value> &stack) const override;
+
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override;
protected:
DIEToTypePtr &GetDIEToType() override;
DIEToVariableSP &GetDIEToVariable() override;
- DIEToClangType &GetForwardDeclDieToClangType() override;
+ DIEToCompilerType &GetForwardDeclDIEToCompilerType() override;
- ClangTypeToDIE &GetForwardDeclClangTypeToDie() override;
+ CompilerTypeToDIE &GetForwardDeclCompilerTypeToDIE() override;
UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() override;
lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) override;
- lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, lldb_private::ConstString type_name,
- bool must_be_implementation) override;
+ lldb::TypeSP
+ FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die,
+ ConstString type_name,
+ bool must_be_implementation) override;
SymbolFileDWARF &GetBaseSymbolFile() const { return m_base_symbol_file; }
@@ -77,5 +83,7 @@ protected:
SymbolFileDWARF &m_base_symbol_file;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H
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 22a921cf6138..223518f0ae82 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -11,6 +11,7 @@
#include "lldb/Core/Declaration.h"
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
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 0947d1e581c5..bf3cbae55e5c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -16,13 +16,15 @@
#include "DWARFDIE.h"
#include "lldb/Core/Declaration.h"
+namespace lldb_private::plugin {
+namespace dwarf {
class UniqueDWARFASTType {
public:
// Constructors and Destructors
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)
+ const Declaration &decl, int32_t byte_size)
: m_type_sp(type_sp), m_die(die), m_declaration(decl),
m_byte_size(byte_size) {}
@@ -44,7 +46,7 @@ public:
lldb::TypeSP m_type_sp;
DWARFDIE m_die;
- lldb_private::Declaration m_declaration;
+ Declaration m_declaration;
int32_t m_byte_size = -1;
};
@@ -60,7 +62,7 @@ public:
m_collection.push_back(entry);
}
- bool Find(const DWARFDIE &die, const lldb_private::Declaration &decl,
+ bool Find(const DWARFDIE &die, const Declaration &decl,
const int32_t byte_size, UniqueDWARFASTType &entry) const;
protected:
@@ -74,14 +76,12 @@ public:
~UniqueDWARFASTTypeMap() = default;
- void Insert(lldb_private::ConstString name,
- const UniqueDWARFASTType &entry) {
+ void Insert(ConstString name, const UniqueDWARFASTType &entry) {
m_collection[name.GetCString()].Append(entry);
}
- bool Find(lldb_private::ConstString name, const DWARFDIE &die,
- const lldb_private::Declaration &decl, const int32_t byte_size,
- UniqueDWARFASTType &entry) const {
+ bool Find(ConstString name, const DWARFDIE &die, const Declaration &decl,
+ const int32_t byte_size, UniqueDWARFASTType &entry) const {
const char *unique_name_cstr = name.GetCString();
collection::const_iterator pos = m_collection.find(unique_name_cstr);
if (pos != m_collection.end()) {
@@ -95,5 +95,7 @@ protected:
typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection;
collection m_collection;
};
+} // namespace dwarf
+} // namespace lldb_private::plugin
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H
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 06cb720b1e9f..25d04f999ad6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -236,7 +236,7 @@ CompileUnitIndex::GetMainSourceFile(const CompilandIndexItem &item) const {
llvm::cantFail(
TypeDeserializer::deserializeAs<StringIdRecord>(file_cvt, file_name));
- llvm::sys::path::Style style = working_dir.String.startswith("/")
+ llvm::sys::path::Style style = working_dir.String.starts_with("/")
? llvm::sys::path::Style::posix
: llvm::sys::path::Style::windows;
if (llvm::sys::path::is_absolute(file_name.String, style))
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 9623daa416bb..75adf7302f00 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -10,10 +10,10 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/StreamBuffer.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/StreamBuffer.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
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 c7ff25e904ab..b79d3e63f72b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -99,18 +99,18 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {
switch (cr.Kind) {
case TypeRecordKind::Class:
- return clang::TTK_Class;
+ return clang::TagTypeKind::Class;
case TypeRecordKind::Struct:
- return clang::TTK_Struct;
+ return clang::TagTypeKind::Struct;
case TypeRecordKind::Union:
- return clang::TTK_Union;
+ return clang::TagTypeKind::Union;
case TypeRecordKind::Interface:
- return clang::TTK_Interface;
+ return clang::TagTypeKind::Interface;
case TypeRecordKind::Enum:
- return clang::TTK_Enum;
+ return clang::TagTypeKind::Enum;
default:
lldbassert(false && "Invalid tag record kind!");
- return clang::TTK_Struct;
+ return clang::TagTypeKind::Struct;
}
}
@@ -608,16 +608,17 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
return {};
clang::TagTypeKind ttk = TranslateUdtKind(record);
- lldb::AccessType access =
- (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic;
+ lldb::AccessType access = (ttk == clang::TagTypeKind::Class)
+ ? lldb::eAccessPrivate
+ : lldb::eAccessPublic;
ClangASTMetadata metadata;
metadata.SetUserID(toOpaqueUid(id));
metadata.SetIsDynamicCXXType(false);
- CompilerType ct =
- m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname,
- ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
+ CompilerType ct = m_clang.CreateRecordType(
+ context, OptionalClangModuleID(), access, uname, llvm::to_underlying(ttk),
+ lldb::eLanguageTypeC_plus_plus, &metadata);
lldbassert(ct.IsValid());
@@ -1263,9 +1264,9 @@ void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) {
clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);
llvm::StringRef ns_name = ns->getName();
- if (ns_name.startswith(qname)) {
+ if (ns_name.starts_with(qname)) {
ns_name = ns_name.drop_front(qname.size());
- if (ns_name.startswith("::"))
+ if (ns_name.starts_with("::"))
GetOrCreateType(tid);
}
}
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 c45db174e534..f28509acbf79 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -9,7 +9,6 @@
#include "PdbFPOProgramToDWARFExpression.h"
#include "CodeViewRegisterMapping.h"
-#include "lldb/Core/StreamBuffer.h"
#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Stream.h"
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 f14fb32621b3..ad0801339936 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -14,8 +14,6 @@
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamBuffer.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -1381,7 +1379,7 @@ bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
for (llvm::StringRef f : cci->m_file_list) {
FileSpec::Style style =
- f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
+ f.starts_with("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
FileSpec spec(f, style);
support_files.Append(spec);
}
@@ -1719,24 +1717,33 @@ void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
bool include_inlines,
SymbolContextList &sc_list) {}
-void SymbolFileNativePDB::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- if (!name)
+void SymbolFileNativePDB::FindTypes(const lldb_private::TypeQuery &query,
+ lldb_private::TypeResults &results) {
+
+ // Make sure we haven't already searched this SymbolFile before.
+ if (results.AlreadySearched(this))
return;
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- // There is an assumption 'name' is not a regex
- FindTypesByName(name.GetStringRef(), max_matches, types);
-}
+ std::vector<TypeIndex> matches =
+ m_index->tpi().findRecordsByName(query.GetTypeBasename().GetStringRef());
-void SymbolFileNativePDB::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {}
+ for (TypeIndex type_idx : matches) {
+ TypeSP type_sp = GetOrCreateType(type_idx);
+ if (!type_sp)
+ continue;
+
+ // We resolved a type. Get the fully qualified name to ensure it matches.
+ ConstString name = type_sp->GetQualifiedName();
+ TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match);
+ if (query.ContextMatches(type_match.GetContextRef())) {
+ results.InsertUnique(type_sp);
+ if (results.Done(query))
+ return;
+ }
+ }
+}
void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
uint32_t max_matches,
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 bf64cd330c1f..9d0458cf7ebf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -140,14 +140,8 @@ public:
std::optional<PdbCompilandSymId> FindSymbolScope(PdbCompilandSymId id);
- void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index cf3868d077c3..fab3ca989c0e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -356,14 +356,14 @@ UdtRecordCompleter::AddMember(TypeSystemClang &clang, Member *field,
case Member::Struct:
case Member::Union: {
clang::TagTypeKind kind = field->kind == Member::Struct
- ? clang::TagTypeKind::TTK_Struct
- : clang::TagTypeKind::TTK_Union;
+ ? clang::TagTypeKind::Struct
+ : clang::TagTypeKind::Union;
ClangASTMetadata metadata;
metadata.SetUserID(pdb->anonymous_id);
metadata.SetIsDynamicCXXType(false);
CompilerType record_ct = clang.CreateRecordType(
- parent_decl_ctx, OptionalClangModuleID(), lldb::eAccessPublic, "", kind,
- lldb::eLanguageTypeC_plus_plus, &metadata);
+ parent_decl_ctx, OptionalClangModuleID(), lldb::eAccessPublic, "",
+ llvm::to_underlying(kind), lldb::eLanguageTypeC_plus_plus, &metadata);
TypeSystemClang::StartTagDeclarationDefinition(record_ct);
ClangASTImporter::LayoutInfo layout;
clang::DeclContext *decl_ctx = clang.GetDeclContextForType(record_ct);
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 5efa5bccb85f..e915bff9e4a4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -49,13 +49,13 @@ using namespace llvm::pdb;
static int TranslateUdtKind(PDB_UdtType pdb_kind) {
switch (pdb_kind) {
case PDB_UdtType::Class:
- return clang::TTK_Class;
+ return llvm::to_underlying(clang::TagTypeKind::Class);
case PDB_UdtType::Struct:
- return clang::TTK_Struct;
+ return llvm::to_underlying(clang::TagTypeKind::Struct);
case PDB_UdtType::Union:
- return clang::TTK_Union;
+ return llvm::to_underlying(clang::TagTypeKind::Union);
case PDB_UdtType::Interface:
- return clang::TTK_Interface;
+ return llvm::to_underlying(clang::TagTypeKind::Interface);
}
llvm_unreachable("unsuported PDB UDT type");
}
@@ -1387,9 +1387,9 @@ void PDBASTParser::AddRecordBases(
auto is_virtual = base->isVirtualBaseClass();
std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
- m_ast.CreateBaseClassSpecifier(base_comp_type.GetOpaqueQualType(),
- access, is_virtual,
- record_kind == clang::TTK_Class);
+ m_ast.CreateBaseClassSpecifier(
+ base_comp_type.GetOpaqueQualType(), access, is_virtual,
+ record_kind == llvm::to_underlying(clang::TagTypeKind::Class));
lldbassert(base_spec);
base_classes.push_back(std::move(base_spec));
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 94023737b2a2..95add31385df 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -9,11 +9,11 @@
#include "PDBLocationToDWARFExpression.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/StreamBuffer.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/StreamBuffer.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
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 78eabc35ebf9..9e1cd8360660 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1446,24 +1446,6 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.Finalize();
}
-void SymbolFilePDB::FindTypes(
- lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) {
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- if (!name)
- return;
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return;
-
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
-
- // There is an assumption 'name' is not a regex
- FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
-}
-
void SymbolFilePDB::DumpClangAST(Stream &s) {
auto type_system_or_err =
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
@@ -1536,26 +1518,24 @@ void SymbolFilePDB::FindTypesByRegex(
}
}
-void SymbolFilePDB::FindTypesByName(
- llvm::StringRef name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches, lldb_private::TypeMap &types) {
+void SymbolFilePDB::FindTypes(const lldb_private::TypeQuery &query,
+ lldb_private::TypeResults &type_results) {
+
+ // Make sure we haven't already searched this SymbolFile before.
+ if (type_results.AlreadySearched(this))
+ return;
+
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+
std::unique_ptr<IPDBEnumSymbols> results;
- if (name.empty())
+ llvm::StringRef basename = query.GetTypeBasename().GetStringRef();
+ if (basename.empty())
return;
results = m_global_scope_up->findAllChildren(PDB_SymType::None);
if (!results)
return;
- uint32_t matches = 0;
-
while (auto result = results->getNext()) {
- if (max_matches > 0 && matches >= max_matches)
- break;
-
- if (MSVCUndecoratedNameParser::DropScope(
- result->getRawSymbol().getName()) != name)
- continue;
switch (result->getSymTag()) {
case PDB_SymType::Enum:
@@ -1568,28 +1548,29 @@ void SymbolFilePDB::FindTypesByName(
continue;
}
+ if (MSVCUndecoratedNameParser::DropScope(
+ result->getRawSymbol().getName()) != basename)
+ continue;
+
// This should cause the type to get cached and stored in the `m_types`
// lookup.
if (!ResolveTypeUID(result->getSymIndexId()))
continue;
- if (parent_decl_ctx.IsValid() &&
- GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx)
- continue;
-
auto iter = m_types.find(result->getSymIndexId());
if (iter == m_types.end())
continue;
- types.Insert(iter->second);
- ++matches;
+ // We resolved a type. Get the fully qualified name to ensure it matches.
+ ConstString name = iter->second->GetQualifiedName();
+ TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match);
+ if (query.ContextMatches(type_match.GetContextRef())) {
+ type_results.InsertUnique(iter->second);
+ if (type_results.Done(query))
+ return;
+ }
}
}
-void SymbolFilePDB::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) {}
-
void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
uint32_t type_mask,
TypeCollection &type_collection) {
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 5b98c6e8b486..01851f1418f3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -134,19 +134,8 @@ public:
std::vector<lldb_private::ConstString> &mangled_names) override;
void AddSymbols(lldb_private::Symtab &symtab) override;
-
- void
- FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
- lldb_private::LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
-
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
uint32_t max_matches, lldb_private::TypeMap &types);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp
new file mode 100644
index 000000000000..9f32d252b22f
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp
@@ -0,0 +1,1149 @@
+//===-- SymbolLocatorDebugSymbols.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 "SymbolLocatorDebugSymbols.h"
+
+#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+#include "lldb/Utility/UUID.h"
+
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/ThreadPool.h"
+
+#include "Host/macosx/cfcpp/CFCBundle.h"
+#include "Host/macosx/cfcpp/CFCData.h"
+#include "Host/macosx/cfcpp/CFCReleaser.h"
+#include "Host/macosx/cfcpp/CFCString.h"
+
+#include "mach/machine.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <cstring>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <optional>
+#include <pwd.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)(
+ CFUUIDRef uuid, CFURLRef exec_url) = nullptr;
+static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) =
+ nullptr;
+
+LLDB_PLUGIN_DEFINE(SymbolLocatorDebugSymbols)
+
+SymbolLocatorDebugSymbols::SymbolLocatorDebugSymbols() : SymbolLocator() {}
+
+void SymbolLocatorDebugSymbols::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
+ LocateExecutableObjectFile, LocateExecutableSymbolFile,
+ DownloadObjectAndSymbolFile, FindSymbolFileInBundle);
+}
+
+void SymbolLocatorDebugSymbols::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+llvm::StringRef SymbolLocatorDebugSymbols::GetPluginDescriptionStatic() {
+ return "DebugSymbols symbol locator.";
+}
+
+SymbolLocator *SymbolLocatorDebugSymbols::CreateInstance() {
+ return new SymbolLocatorDebugSymbols();
+}
+
+std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile(
+ const ModuleSpec &module_spec) {
+ Log *log = GetLog(LLDBLog::Host);
+ if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+ LLDB_LOGF(log, "Spotlight lookup for .dSYM bundles is disabled.");
+ return {};
+ }
+ ModuleSpec return_module_spec;
+ return_module_spec = module_spec;
+ return_module_spec.GetFileSpec().Clear();
+ return_module_spec.GetSymbolFileSpec().Clear();
+
+ const UUID *uuid = module_spec.GetUUIDPtr();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+
+ int items_found = 0;
+
+ if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr ||
+ g_dlsym_DBGCopyDSYMPropertyLists == nullptr) {
+ void *handle = dlopen(
+ "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols",
+ RTLD_LAZY | RTLD_LOCAL);
+ if (handle) {
+ g_dlsym_DBGCopyFullDSYMURLForUUID =
+ (CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle,
+ "DBGCopyFullDSYMURLForUUID");
+ g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym(
+ handle, "DBGCopyDSYMPropertyLists");
+ }
+ }
+
+ if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr ||
+ g_dlsym_DBGCopyDSYMPropertyLists == nullptr) {
+ return {};
+ }
+
+ if (uuid && uuid->IsValid()) {
+ // Try and locate the dSYM file using DebugSymbols first
+ llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
+ if (module_uuid.size() == 16) {
+ CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
+ NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
+ module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
+ module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11],
+ module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15]));
+
+ if (module_uuid_ref.get()) {
+ CFCReleaser<CFURLRef> exec_url;
+ const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+ if (exec_fspec) {
+ char exec_cf_path[PATH_MAX];
+ if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
+ exec_url.reset(::CFURLCreateFromFileSystemRepresentation(
+ NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path),
+ FALSE));
+ }
+
+ CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID(
+ module_uuid_ref.get(), exec_url.get()));
+ char path[PATH_MAX];
+
+ if (dsym_url.get()) {
+ if (::CFURLGetFileSystemRepresentation(
+ dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+ LLDB_LOGF(log,
+ "DebugSymbols framework returned dSYM path of %s for "
+ "UUID %s -- looking for the dSYM",
+ path, uuid->GetAsString().c_str());
+ FileSpec dsym_filespec(path);
+ if (path[0] == '~')
+ FileSystem::Instance().Resolve(dsym_filespec);
+
+ if (FileSystem::Instance().IsDirectory(dsym_filespec)) {
+ dsym_filespec = PluginManager::FindSymbolFileInBundle(
+ dsym_filespec, uuid, arch);
+ ++items_found;
+ } else {
+ ++items_found;
+ }
+ return_module_spec.GetSymbolFileSpec() = dsym_filespec;
+ }
+
+ bool success = false;
+ if (log) {
+ if (::CFURLGetFileSystemRepresentation(
+ dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+ LLDB_LOGF(log,
+ "DebugSymbols framework returned dSYM path of %s for "
+ "UUID %s -- looking for an exec file",
+ path, uuid->GetAsString().c_str());
+ }
+ }
+
+ CFCReleaser<CFDictionaryRef> dict(
+ g_dlsym_DBGCopyDSYMPropertyLists(dsym_url.get()));
+ CFDictionaryRef uuid_dict = NULL;
+ if (dict.get()) {
+ CFCString uuid_cfstr(uuid->GetAsString().c_str());
+ uuid_dict = static_cast<CFDictionaryRef>(
+ ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get()));
+ }
+
+ // Check to see if we have the file on the local filesystem.
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ ModuleSpec exe_spec;
+ exe_spec.GetFileSpec() = module_spec.GetFileSpec();
+ exe_spec.GetUUID() = module_spec.GetUUID();
+ ModuleSP module_sp;
+ module_sp.reset(new Module(exe_spec));
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->MatchesModuleSpec(exe_spec)) {
+ success = true;
+ return_module_spec.GetFileSpec() = module_spec.GetFileSpec();
+ LLDB_LOGF(log, "using original binary filepath %s for UUID %s",
+ module_spec.GetFileSpec().GetPath().c_str(),
+ uuid->GetAsString().c_str());
+ ++items_found;
+ }
+ }
+
+ // Check if the requested image is in our shared cache.
+ if (!success) {
+ SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(
+ module_spec.GetFileSpec().GetPath());
+
+ // If we found it and it has the correct UUID, let's proceed with
+ // creating a module from the memory contents.
+ if (image_info.uuid && (!module_spec.GetUUID() ||
+ module_spec.GetUUID() == image_info.uuid)) {
+ success = true;
+ return_module_spec.GetFileSpec() = module_spec.GetFileSpec();
+ LLDB_LOGF(log,
+ "using binary from shared cache for filepath %s for "
+ "UUID %s",
+ module_spec.GetFileSpec().GetPath().c_str(),
+ uuid->GetAsString().c_str());
+ ++items_found;
+ }
+ }
+
+ // Use the DBGSymbolRichExecutable filepath if present
+ if (!success && uuid_dict) {
+ CFStringRef exec_cf_path =
+ static_cast<CFStringRef>(::CFDictionaryGetValue(
+ uuid_dict, CFSTR("DBGSymbolRichExecutable")));
+ if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
+ exec_cf_path, path, sizeof(path))) {
+ LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s",
+ path, uuid->GetAsString().c_str());
+ ++items_found;
+ FileSpec exec_filespec(path);
+ if (path[0] == '~')
+ FileSystem::Instance().Resolve(exec_filespec);
+ if (FileSystem::Instance().Exists(exec_filespec)) {
+ success = true;
+ return_module_spec.GetFileSpec() = exec_filespec;
+ }
+ }
+ }
+
+ // Look next to the dSYM for the binary file.
+ if (!success) {
+ if (::CFURLGetFileSystemRepresentation(
+ dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+ char *dsym_extension_pos = ::strstr(path, ".dSYM");
+ if (dsym_extension_pos) {
+ *dsym_extension_pos = '\0';
+ LLDB_LOGF(log,
+ "Looking for executable binary next to dSYM "
+ "bundle with name with name %s",
+ path);
+ FileSpec file_spec(path);
+ FileSystem::Instance().Resolve(file_spec);
+ ModuleSpecList module_specs;
+ ModuleSpec matched_module_spec;
+ using namespace llvm::sys::fs;
+ switch (get_file_type(file_spec.GetPath())) {
+
+ case file_type::directory_file: // Bundle directory?
+ {
+ CFCBundle bundle(path);
+ CFCReleaser<CFURLRef> bundle_exe_url(
+ bundle.CopyExecutableURL());
+ if (bundle_exe_url.get()) {
+ if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
+ true, (UInt8 *)path,
+ sizeof(path) - 1)) {
+ FileSpec bundle_exe_file_spec(path);
+ FileSystem::Instance().Resolve(bundle_exe_file_spec);
+ if (ObjectFile::GetModuleSpecifications(
+ bundle_exe_file_spec, 0, 0, module_specs) &&
+ module_specs.FindMatchingModuleSpec(
+ module_spec, matched_module_spec))
+
+ {
+ ++items_found;
+ return_module_spec.GetFileSpec() = bundle_exe_file_spec;
+ LLDB_LOGF(log,
+ "Executable binary %s next to dSYM is "
+ "compatible; using",
+ path);
+ }
+ }
+ }
+ } break;
+
+ case file_type::fifo_file: // Forget pipes
+ case file_type::socket_file: // We can't process socket files
+ case file_type::file_not_found: // File doesn't exist...
+ case file_type::status_error:
+ break;
+
+ case file_type::type_unknown:
+ case file_type::regular_file:
+ case file_type::symlink_file:
+ case file_type::block_file:
+ case file_type::character_file:
+ if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0,
+ module_specs) &&
+ module_specs.FindMatchingModuleSpec(module_spec,
+ matched_module_spec))
+
+ {
+ ++items_found;
+ return_module_spec.GetFileSpec() = file_spec;
+ LLDB_LOGF(log,
+ "Executable binary %s next to dSYM is "
+ "compatible; using",
+ path);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (items_found)
+ return return_module_spec;
+
+ return {};
+}
+
+std::optional<FileSpec> SymbolLocatorDebugSymbols::FindSymbolFileInBundle(
+ const FileSpec &dsym_bundle_fspec, const UUID *uuid, const ArchSpec *arch) {
+ std::string dsym_bundle_path = dsym_bundle_fspec.GetPath();
+ llvm::SmallString<128> buffer(dsym_bundle_path);
+ llvm::sys::path::append(buffer, "Contents", "Resources", "DWARF");
+
+ std::error_code EC;
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs =
+ FileSystem::Instance().GetVirtualFileSystem();
+ llvm::vfs::recursive_directory_iterator Iter(*vfs, buffer.str(), EC);
+ llvm::vfs::recursive_directory_iterator End;
+ for (; Iter != End && !EC; Iter.increment(EC)) {
+ llvm::ErrorOr<llvm::vfs::Status> Status = vfs->status(Iter->path());
+ if (Status->isDirectory())
+ continue;
+
+ FileSpec dsym_fspec(Iter->path());
+ ModuleSpecList module_specs;
+ if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
+ ModuleSpec spec;
+ for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ assert(got_spec); // The call has side-effects so can't be inlined.
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ if ((uuid == nullptr ||
+ (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+ (arch == nullptr ||
+ (spec.GetArchitecturePtr() &&
+ spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+ return dsym_fspec;
+ }
+ }
+ }
+ }
+
+ return {};
+}
+
+static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
+ const ArchSpec *arch,
+ const lldb_private::UUID *uuid) {
+ ModuleSpecList module_specs;
+ if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) {
+ ModuleSpec spec;
+ for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ assert(got_spec);
+ if ((uuid == nullptr || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+ (arch == nullptr ||
+ (spec.GetArchitecturePtr() &&
+ spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
+// return true if there is a matching dSYM bundle next to the exec_fspec,
+// and return that value in dsym_fspec.
+// If there is a .dSYM.yaa compressed archive next to the exec_fspec,
+// call through PluginManager::DownloadObjectAndSymbolFile to download the
+// expanded/uncompressed dSYM and return that filepath in dsym_fspec.
+static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
+ const FileSpec &exec_fspec,
+ FileSpec &dsym_fspec) {
+ ConstString filename = exec_fspec.GetFilename();
+ FileSpec dsym_directory = exec_fspec;
+ dsym_directory.RemoveLastPathComponent();
+
+ std::string dsym_filename = filename.AsCString();
+ dsym_filename += ".dSYM";
+ dsym_directory.AppendPathComponent(dsym_filename);
+ dsym_directory.AppendPathComponent("Contents");
+ dsym_directory.AppendPathComponent("Resources");
+ dsym_directory.AppendPathComponent("DWARF");
+
+ if (FileSystem::Instance().Exists(dsym_directory)) {
+
+ // See if the binary name exists in the dSYM DWARF
+ // subdir.
+ dsym_fspec = dsym_directory;
+ dsym_fspec.AppendPathComponent(filename.AsCString());
+ if (FileSystem::Instance().Exists(dsym_fspec) &&
+ FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(),
+ mod_spec.GetUUIDPtr())) {
+ return true;
+ }
+
+ // See if we have "../CF.framework" - so we'll look for
+ // CF.framework.dSYM/Contents/Resources/DWARF/CF
+ // We need to drop the last suffix after '.' to match
+ // 'CF' in the DWARF subdir.
+ std::string binary_name(filename.AsCString());
+ auto last_dot = binary_name.find_last_of('.');
+ if (last_dot != std::string::npos) {
+ binary_name.erase(last_dot);
+ dsym_fspec = dsym_directory;
+ dsym_fspec.AppendPathComponent(binary_name);
+ if (FileSystem::Instance().Exists(dsym_fspec) &&
+ FileAtPathContainsArchAndUUID(dsym_fspec,
+ mod_spec.GetArchitecturePtr(),
+ mod_spec.GetUUIDPtr())) {
+ return true;
+ }
+ }
+ }
+
+ // See if we have a .dSYM.yaa next to this executable path.
+ FileSpec dsym_yaa_fspec = exec_fspec;
+ dsym_yaa_fspec.RemoveLastPathComponent();
+ std::string dsym_yaa_filename = filename.AsCString();
+ dsym_yaa_filename += ".dSYM.yaa";
+ dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
+
+ if (FileSystem::Instance().Exists(dsym_yaa_fspec)) {
+ ModuleSpec mutable_mod_spec = mod_spec;
+ Status error;
+ if (PluginManager::DownloadObjectAndSymbolFile(mutable_mod_spec, error,
+ true) &&
+ FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) {
+ dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Given a ModuleSpec with a FileSpec and optionally uuid/architecture
+// filled in, look for a .dSYM bundle next to that binary. Returns true
+// if a .dSYM bundle is found, and that path is returned in the dsym_fspec
+// FileSpec.
+//
+// This routine looks a few directory layers above the given exec_path -
+// exec_path might be /System/Library/Frameworks/CF.framework/CF and the
+// dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
+//
+// If there is a .dSYM.yaa compressed archive found next to the binary,
+// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
+static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
+ FileSpec &dsym_fspec) {
+ Log *log = GetLog(LLDBLog::Host);
+ const FileSpec &exec_fspec = module_spec.GetFileSpec();
+ if (exec_fspec) {
+ if (::LookForDsymNextToExecutablePath(module_spec, exec_fspec,
+ dsym_fspec)) {
+ if (log) {
+ LLDB_LOGF(log, "dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
+ }
+ return true;
+ } else {
+ FileSpec parent_dirs = exec_fspec;
+
+ // Remove the binary name from the FileSpec
+ parent_dirs.RemoveLastPathComponent();
+
+ // Add a ".dSYM" name to each directory component of the path,
+ // stripping off components. e.g. we may have a binary like
+ // /S/L/F/Foundation.framework/Versions/A/Foundation and
+ // /S/L/F/Foundation.framework.dSYM
+ //
+ // so we'll need to start with
+ // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
+ // "A", and if that doesn't exist, strip off the "A" and try it again
+ // with "Versions", etc., until we find a dSYM bundle or we've
+ // stripped off enough path components that there's no need to
+ // continue.
+
+ for (int i = 0; i < 4; i++) {
+ // Does this part of the path have a "." character - could it be a
+ // bundle's top level directory?
+ const char *fn = parent_dirs.GetFilename().AsCString();
+ if (fn == nullptr)
+ break;
+ if (::strchr(fn, '.') != nullptr) {
+ if (::LookForDsymNextToExecutablePath(module_spec, parent_dirs,
+ dsym_fspec)) {
+ if (log) {
+ LLDB_LOGF(log, "dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
+ }
+ return true;
+ }
+ }
+ parent_dirs.RemoveLastPathComponent();
+ }
+ }
+ }
+ dsym_fspec.Clear();
+ return false;
+}
+
+static int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+ ModuleSpec &return_module_spec) {
+ Log *log = GetLog(LLDBLog::Host);
+ if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+ LLDB_LOGF(log, "Spotlight lookup for .dSYM bundles is disabled.");
+ return 0;
+ }
+
+ return_module_spec = module_spec;
+ return_module_spec.GetFileSpec().Clear();
+ return_module_spec.GetSymbolFileSpec().Clear();
+
+ const UUID *uuid = module_spec.GetUUIDPtr();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+
+ int items_found = 0;
+
+ if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr ||
+ g_dlsym_DBGCopyDSYMPropertyLists == nullptr) {
+ void *handle = dlopen(
+ "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols",
+ RTLD_LAZY | RTLD_LOCAL);
+ if (handle) {
+ g_dlsym_DBGCopyFullDSYMURLForUUID =
+ (CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle,
+ "DBGCopyFullDSYMURLForUUID");
+ g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym(
+ handle, "DBGCopyDSYMPropertyLists");
+ }
+ }
+
+ if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr ||
+ g_dlsym_DBGCopyDSYMPropertyLists == nullptr) {
+ return items_found;
+ }
+
+ if (uuid && uuid->IsValid()) {
+ // Try and locate the dSYM file using DebugSymbols first
+ llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
+ if (module_uuid.size() == 16) {
+ CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
+ NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
+ module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
+ module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11],
+ module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15]));
+
+ if (module_uuid_ref.get()) {
+ CFCReleaser<CFURLRef> exec_url;
+ const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+ if (exec_fspec) {
+ char exec_cf_path[PATH_MAX];
+ if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
+ exec_url.reset(::CFURLCreateFromFileSystemRepresentation(
+ NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path),
+ FALSE));
+ }
+
+ CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID(
+ module_uuid_ref.get(), exec_url.get()));
+ char path[PATH_MAX];
+
+ if (dsym_url.get()) {
+ if (::CFURLGetFileSystemRepresentation(
+ dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+ LLDB_LOGF(log,
+ "DebugSymbols framework returned dSYM path of %s for "
+ "UUID %s -- looking for the dSYM",
+ path, uuid->GetAsString().c_str());
+ FileSpec dsym_filespec(path);
+ if (path[0] == '~')
+ FileSystem::Instance().Resolve(dsym_filespec);
+
+ if (FileSystem::Instance().IsDirectory(dsym_filespec)) {
+ dsym_filespec = PluginManager::FindSymbolFileInBundle(
+ dsym_filespec, uuid, arch);
+ ++items_found;
+ } else {
+ ++items_found;
+ }
+ return_module_spec.GetSymbolFileSpec() = dsym_filespec;
+ }
+
+ bool success = false;
+ if (log) {
+ if (::CFURLGetFileSystemRepresentation(
+ dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+ LLDB_LOGF(log,
+ "DebugSymbols framework returned dSYM path of %s for "
+ "UUID %s -- looking for an exec file",
+ path, uuid->GetAsString().c_str());
+ }
+ }
+
+ CFCReleaser<CFDictionaryRef> dict(
+ g_dlsym_DBGCopyDSYMPropertyLists(dsym_url.get()));
+ CFDictionaryRef uuid_dict = NULL;
+ if (dict.get()) {
+ CFCString uuid_cfstr(uuid->GetAsString().c_str());
+ uuid_dict = static_cast<CFDictionaryRef>(
+ ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get()));
+ }
+
+ // Check to see if we have the file on the local filesystem.
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ ModuleSpec exe_spec;
+ exe_spec.GetFileSpec() = module_spec.GetFileSpec();
+ exe_spec.GetUUID() = module_spec.GetUUID();
+ ModuleSP module_sp;
+ module_sp.reset(new Module(exe_spec));
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->MatchesModuleSpec(exe_spec)) {
+ success = true;
+ return_module_spec.GetFileSpec() = module_spec.GetFileSpec();
+ LLDB_LOGF(log, "using original binary filepath %s for UUID %s",
+ module_spec.GetFileSpec().GetPath().c_str(),
+ uuid->GetAsString().c_str());
+ ++items_found;
+ }
+ }
+
+ // Check if the requested image is in our shared cache.
+ if (!success) {
+ SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(
+ module_spec.GetFileSpec().GetPath());
+
+ // If we found it and it has the correct UUID, let's proceed with
+ // creating a module from the memory contents.
+ if (image_info.uuid && (!module_spec.GetUUID() ||
+ module_spec.GetUUID() == image_info.uuid)) {
+ success = true;
+ return_module_spec.GetFileSpec() = module_spec.GetFileSpec();
+ LLDB_LOGF(log,
+ "using binary from shared cache for filepath %s for "
+ "UUID %s",
+ module_spec.GetFileSpec().GetPath().c_str(),
+ uuid->GetAsString().c_str());
+ ++items_found;
+ }
+ }
+
+ // Use the DBGSymbolRichExecutable filepath if present
+ if (!success && uuid_dict) {
+ CFStringRef exec_cf_path =
+ static_cast<CFStringRef>(::CFDictionaryGetValue(
+ uuid_dict, CFSTR("DBGSymbolRichExecutable")));
+ if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
+ exec_cf_path, path, sizeof(path))) {
+ LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s",
+ path, uuid->GetAsString().c_str());
+ ++items_found;
+ FileSpec exec_filespec(path);
+ if (path[0] == '~')
+ FileSystem::Instance().Resolve(exec_filespec);
+ if (FileSystem::Instance().Exists(exec_filespec)) {
+ success = true;
+ return_module_spec.GetFileSpec() = exec_filespec;
+ }
+ }
+ }
+
+ // Look next to the dSYM for the binary file.
+ if (!success) {
+ if (::CFURLGetFileSystemRepresentation(
+ dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+ char *dsym_extension_pos = ::strstr(path, ".dSYM");
+ if (dsym_extension_pos) {
+ *dsym_extension_pos = '\0';
+ LLDB_LOGF(log,
+ "Looking for executable binary next to dSYM "
+ "bundle with name with name %s",
+ path);
+ FileSpec file_spec(path);
+ FileSystem::Instance().Resolve(file_spec);
+ ModuleSpecList module_specs;
+ ModuleSpec matched_module_spec;
+ using namespace llvm::sys::fs;
+ switch (get_file_type(file_spec.GetPath())) {
+
+ case file_type::directory_file: // Bundle directory?
+ {
+ CFCBundle bundle(path);
+ CFCReleaser<CFURLRef> bundle_exe_url(
+ bundle.CopyExecutableURL());
+ if (bundle_exe_url.get()) {
+ if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
+ true, (UInt8 *)path,
+ sizeof(path) - 1)) {
+ FileSpec bundle_exe_file_spec(path);
+ FileSystem::Instance().Resolve(bundle_exe_file_spec);
+ if (ObjectFile::GetModuleSpecifications(
+ bundle_exe_file_spec, 0, 0, module_specs) &&
+ module_specs.FindMatchingModuleSpec(
+ module_spec, matched_module_spec))
+
+ {
+ ++items_found;
+ return_module_spec.GetFileSpec() = bundle_exe_file_spec;
+ LLDB_LOGF(log,
+ "Executable binary %s next to dSYM is "
+ "compatible; using",
+ path);
+ }
+ }
+ }
+ } break;
+
+ case file_type::fifo_file: // Forget pipes
+ case file_type::socket_file: // We can't process socket files
+ case file_type::file_not_found: // File doesn't exist...
+ case file_type::status_error:
+ break;
+
+ case file_type::type_unknown:
+ case file_type::regular_file:
+ case file_type::symlink_file:
+ case file_type::block_file:
+ case file_type::character_file:
+ if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0,
+ module_specs) &&
+ module_specs.FindMatchingModuleSpec(module_spec,
+ matched_module_spec))
+
+ {
+ ++items_found;
+ return_module_spec.GetFileSpec() = file_spec;
+ LLDB_LOGF(log,
+ "Executable binary %s next to dSYM is "
+ "compatible; using",
+ path);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return items_found;
+}
+
+std::optional<FileSpec> SymbolLocatorDebugSymbols::LocateExecutableSymbolFile(
+ const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
+ const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+ const UUID *uuid = module_spec.GetUUIDPtr();
+
+ LLDB_SCOPED_TIMERF(
+ "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
+ exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
+ arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
+
+ FileSpec symbol_fspec;
+ ModuleSpec dsym_module_spec;
+ // First try and find the dSYM in the same directory as the executable or in
+ // an appropriate parent directory
+ if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) {
+ // We failed to easily find the dSYM above, so use DebugSymbols
+ LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec);
+ } else {
+ dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
+ }
+
+ return dsym_module_spec.GetSymbolFileSpec();
+}
+
+static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
+ ModuleSpec &module_spec,
+ Status &error,
+ const std::string &command) {
+ Log *log = GetLog(LLDBLog::Host);
+ bool success = false;
+ if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
+ std::string str;
+ CFStringRef cf_str;
+ CFDictionaryRef cf_dict;
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGError"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ if (CFCString::FileSystemRepresentation(cf_str, str)) {
+ std::string errorstr = command;
+ errorstr += ":\n";
+ errorstr += str;
+ error.SetErrorString(errorstr);
+ }
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue(
+ (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ if (CFCString::FileSystemRepresentation(cf_str, str)) {
+ module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+ LLDB_LOGF(log,
+ "From dsymForUUID plist: Symbol rich executable is at '%s'",
+ str.c_str());
+ }
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGDSYMPath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ if (CFCString::FileSystemRepresentation(cf_str, str)) {
+ module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
+ FileSpec::Style::native);
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+ success = true;
+ LLDB_LOGF(log, "From dsymForUUID plist: dSYM is at '%s'", str.c_str());
+ }
+ }
+
+ std::string DBGBuildSourcePath;
+ std::string DBGSourcePath;
+
+ // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
+ // If DBGVersion 2, strip last two components of path remappings from
+ // entries to fix an issue with a specific set of
+ // DBGSourcePathRemapping entries that lldb worked
+ // with.
+ // If DBGVersion 3, trust & use the source path remappings as-is.
+ //
+ cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
+ (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
+ if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
+ // If we see DBGVersion with a value of 2 or higher, this is a new style
+ // DBGSourcePathRemapping dictionary
+ bool new_style_source_remapping_dictionary = false;
+ bool do_truncate_remapping_names = false;
+ std::string original_DBGSourcePath_value = DBGSourcePath;
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGVersion"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ std::string version;
+ CFCString::FileSystemRepresentation(cf_str, version);
+ if (!version.empty() && isdigit(version[0])) {
+ int version_number = atoi(version.c_str());
+ if (version_number > 1) {
+ new_style_source_remapping_dictionary = true;
+ }
+ if (version_number == 2) {
+ do_truncate_remapping_names = true;
+ }
+ }
+ }
+
+ CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
+ if (kv_pair_count > 0) {
+ CFStringRef *keys =
+ (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
+ CFStringRef *values =
+ (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
+ if (keys != nullptr && values != nullptr) {
+ CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
+ (const void **)keys,
+ (const void **)values);
+ }
+ for (CFIndex i = 0; i < kv_pair_count; i++) {
+ DBGBuildSourcePath.clear();
+ DBGSourcePath.clear();
+ if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
+ }
+ if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
+ }
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ // In the "old style" DBGSourcePathRemapping dictionary, the
+ // DBGSourcePath values (the "values" half of key-value path pairs)
+ // were wrong. Ignore them and use the universal DBGSourcePath
+ // string from earlier.
+ if (new_style_source_remapping_dictionary &&
+ !original_DBGSourcePath_value.empty()) {
+ DBGSourcePath = original_DBGSourcePath_value;
+ }
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ // With version 2 of DBGSourcePathRemapping, we can chop off the
+ // last two filename parts from the source remapping and get a more
+ // general source remapping that still works. Add this as another
+ // option in addition to the full source path remap.
+ module_spec.GetSourceMappingList().Append(DBGBuildSourcePath,
+ DBGSourcePath, true);
+ if (do_truncate_remapping_names) {
+ FileSpec build_path(DBGBuildSourcePath.c_str());
+ FileSpec source_path(DBGSourcePath.c_str());
+ build_path.RemoveLastPathComponent();
+ build_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ module_spec.GetSourceMappingList().Append(
+ build_path.GetPath(), source_path.GetPath(), true);
+ }
+ }
+ }
+ if (keys)
+ free(keys);
+ if (values)
+ free(values);
+ }
+ }
+
+ // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
+ // source remappings list.
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGBuildSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+ }
+
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_spec.GetSourceMappingList().Append(DBGBuildSourcePath,
+ DBGSourcePath, true);
+ }
+ }
+ return success;
+}
+
+/// It's expensive to check for the DBGShellCommands defaults setting. Only do
+/// it once per lldb run and cache the result.
+static llvm::StringRef GetDbgShellCommand() {
+ static std::once_flag g_once_flag;
+ static std::string g_dbgshell_command;
+ std::call_once(g_once_flag, [&]() {
+ CFTypeRef defaults_setting = CFPreferencesCopyAppValue(
+ CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols"));
+ if (defaults_setting &&
+ CFGetTypeID(defaults_setting) == CFStringGetTypeID()) {
+ char buffer[PATH_MAX];
+ if (CFStringGetCString((CFStringRef)defaults_setting, buffer,
+ sizeof(buffer), kCFStringEncodingUTF8)) {
+ g_dbgshell_command = buffer;
+ }
+ }
+ if (defaults_setting) {
+ CFRelease(defaults_setting);
+ }
+ });
+ return g_dbgshell_command;
+}
+
+/// Get the dsymForUUID executable and cache the result so we don't end up
+/// stat'ing the binary over and over.
+static FileSpec GetDsymForUUIDExecutable() {
+ // The LLDB_APPLE_DSYMFORUUID_EXECUTABLE environment variable is used by the
+ // test suite to override the dsymForUUID location. Because we must be able
+ // to change the value within a single test, don't bother caching it.
+ if (const char *dsymForUUID_env =
+ getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE")) {
+ FileSpec dsymForUUID_executable(dsymForUUID_env);
+ FileSystem::Instance().Resolve(dsymForUUID_executable);
+ if (FileSystem::Instance().Exists(dsymForUUID_executable))
+ return dsymForUUID_executable;
+ }
+
+ static std::once_flag g_once_flag;
+ static FileSpec g_dsymForUUID_executable;
+ std::call_once(g_once_flag, [&]() {
+ // Try the DBGShellCommand.
+ llvm::StringRef dbgshell_command = GetDbgShellCommand();
+ if (!dbgshell_command.empty()) {
+ g_dsymForUUID_executable = FileSpec(dbgshell_command);
+ FileSystem::Instance().Resolve(g_dsymForUUID_executable);
+ if (FileSystem::Instance().Exists(g_dsymForUUID_executable))
+ return;
+ }
+
+ // Try dsymForUUID in /usr/local/bin
+ {
+ g_dsymForUUID_executable = FileSpec("/usr/local/bin/dsymForUUID");
+ if (FileSystem::Instance().Exists(g_dsymForUUID_executable))
+ return;
+ }
+
+ // We couldn't find the dsymForUUID binary.
+ g_dsymForUUID_executable = {};
+ });
+ return g_dsymForUUID_executable;
+}
+
+bool SymbolLocatorDebugSymbols::DownloadObjectAndSymbolFile(
+ ModuleSpec &module_spec, Status &error, bool force_lookup,
+ bool copy_executable) {
+ const UUID *uuid_ptr = module_spec.GetUUIDPtr();
+ const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
+
+ // If \a dbgshell_command is set, the user has specified
+ // forced symbol lookup via that command. We'll get the
+ // path back from GetDsymForUUIDExecutable() later.
+ llvm::StringRef dbgshell_command = GetDbgShellCommand();
+
+ // If forced lookup isn't set, by the user's \a dbgshell_command or
+ // by the \a force_lookup argument, exit this method.
+ if (!force_lookup && dbgshell_command.empty())
+ return false;
+
+ // We need a UUID or valid existing FileSpec.
+ if (!uuid_ptr &&
+ (!file_spec_ptr || !FileSystem::Instance().Exists(*file_spec_ptr)))
+ return false;
+
+ // We need a dsymForUUID binary or an equivalent executable/script.
+ FileSpec dsymForUUID_exe_spec = GetDsymForUUIDExecutable();
+ if (!dsymForUUID_exe_spec)
+ return false;
+
+ const std::string dsymForUUID_exe_path = dsymForUUID_exe_spec.GetPath();
+ const std::string uuid_str = uuid_ptr ? uuid_ptr->GetAsString() : "";
+ const std::string file_path_str =
+ file_spec_ptr ? file_spec_ptr->GetPath() : "";
+
+ Log *log = GetLog(LLDBLog::Host);
+
+ // Create the dsymForUUID command.
+ StreamString command;
+ const char *copy_executable_arg = copy_executable ? "--copyExecutable " : "";
+ if (!uuid_str.empty()) {
+ command.Printf("%s --ignoreNegativeCache %s%s",
+ dsymForUUID_exe_path.c_str(), copy_executable_arg,
+ uuid_str.c_str());
+ LLDB_LOGF(log, "Calling %s with UUID %s to find dSYM: %s",
+ dsymForUUID_exe_path.c_str(), uuid_str.c_str(),
+ command.GetString().data());
+ } else if (!file_path_str.empty()) {
+ command.Printf("%s --ignoreNegativeCache %s%s",
+ dsymForUUID_exe_path.c_str(), copy_executable_arg,
+ file_path_str.c_str());
+ LLDB_LOGF(log, "Calling %s with file %s to find dSYM: %s",
+ dsymForUUID_exe_path.c_str(), file_path_str.c_str(),
+ command.GetString().data());
+ } else {
+ return false;
+ }
+
+ // Invoke dsymForUUID.
+ int exit_status = -1;
+ int signo = -1;
+ std::string command_output;
+ error = Host::RunShellCommand(
+ command.GetData(),
+ FileSpec(), // current working directory
+ &exit_status, // Exit status
+ &signo, // Signal int *
+ &command_output, // Command output
+ std::chrono::seconds(
+ 640), // Large timeout to allow for long dsym download times
+ false); // Don't run in a shell (we don't need shell expansion)
+
+ if (error.Fail() || exit_status != 0 || command_output.empty()) {
+ LLDB_LOGF(log, "'%s' failed (exit status: %d, error: '%s', output: '%s')",
+ command.GetData(), exit_status, error.AsCString(),
+ command_output.c_str());
+ return false;
+ }
+
+ CFCData data(
+ CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)command_output.data(),
+ command_output.size(), kCFAllocatorNull));
+
+ CFCReleaser<CFDictionaryRef> plist(
+ (CFDictionaryRef)::CFPropertyListCreateWithData(
+ NULL, data.get(), kCFPropertyListImmutable, NULL, NULL));
+
+ if (!plist.get()) {
+ LLDB_LOGF(log, "'%s' failed: output is not a valid plist",
+ command.GetData());
+ return false;
+ }
+
+ if (CFGetTypeID(plist.get()) != CFDictionaryGetTypeID()) {
+ LLDB_LOGF(log, "'%s' failed: output plist is not a valid CFDictionary",
+ command.GetData());
+ return false;
+ }
+
+ if (!uuid_str.empty()) {
+ CFCString uuid_cfstr(uuid_str.c_str());
+ CFDictionaryRef uuid_dict =
+ (CFDictionaryRef)CFDictionaryGetValue(plist.get(), uuid_cfstr.get());
+ return GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec, error,
+ command.GetData());
+ }
+
+ if (const CFIndex num_values = ::CFDictionaryGetCount(plist.get())) {
+ std::vector<CFStringRef> keys(num_values, NULL);
+ std::vector<CFDictionaryRef> values(num_values, NULL);
+ ::CFDictionaryGetKeysAndValues(plist.get(), NULL,
+ (const void **)&values[0]);
+ if (num_values == 1) {
+ return GetModuleSpecInfoFromUUIDDictionary(values[0], module_spec, error,
+ command.GetData());
+ }
+
+ for (CFIndex i = 0; i < num_values; ++i) {
+ ModuleSpec curr_module_spec;
+ if (GetModuleSpecInfoFromUUIDDictionary(values[i], curr_module_spec,
+ error, command.GetData())) {
+ if (module_spec.GetArchitecture().IsCompatibleMatch(
+ curr_module_spec.GetArchitecture())) {
+ module_spec = curr_module_spec;
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.h b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.h
new file mode 100644
index 000000000000..efbe68bc5dae
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.h
@@ -0,0 +1,68 @@
+//===-- SymbolLocatorDebugSymbols.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_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H
+
+#include "lldb/Symbol/SymbolLocator.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class SymbolLocatorDebugSymbols : public SymbolLocator {
+public:
+ SymbolLocatorDebugSymbols();
+
+ static void Initialize();
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "DebugSymbols"; }
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolLocator *CreateInstance();
+
+ /// PluginInterface protocol.
+ /// \{
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+ /// \}
+
+ // Locate the executable file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using the
+ // current computers global settings.
+ static std::optional<ModuleSpec>
+ LocateExecutableObjectFile(const ModuleSpec &module_spec);
+
+ // Locate the symbol file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using the
+ // current computers global settings.
+ static std::optional<FileSpec>
+ LocateExecutableSymbolFile(const ModuleSpec &module_spec,
+ const FileSpecList &default_search_paths);
+
+ // Locate the object and symbol file given a module specification.
+ //
+ // Locating the file can try to download the file from a corporate build
+ // repository, or using any other means necessary to locate both the
+ // unstripped object file and the debug symbols. The force_lookup argument
+ // controls whether the external program is called unconditionally to find
+ // the symbol file, or if the user's settings are checked to see if they've
+ // enabled the external program before calling.
+ static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+ Status &error, bool force_lookup,
+ bool copy_executable);
+
+ static std::optional<FileSpec>
+ FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, const UUID *uuid,
+ const ArchSpec *arch);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp
new file mode 100644
index 000000000000..111be6be3652
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp
@@ -0,0 +1,142 @@
+//===-- SymbolLocatorDebuginfod.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 "SymbolLocatorDebuginfod.h"
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/Args.h"
+
+#include "llvm/Debuginfod/Debuginfod.h"
+#include "llvm/Debuginfod/HTTPClient.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(SymbolLocatorDebuginfod)
+
+namespace {
+
+#define LLDB_PROPERTIES_symbollocatordebuginfod
+#include "SymbolLocatorDebuginfodProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_symbollocatordebuginfod
+#include "SymbolLocatorDebuginfodPropertiesEnum.inc"
+};
+
+class PluginProperties : public Properties {
+public:
+ static llvm::StringRef GetSettingName() {
+ return SymbolLocatorDebuginfod::GetPluginNameStatic();
+ }
+
+ PluginProperties() {
+ m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
+ m_collection_sp->Initialize(g_symbollocatordebuginfod_properties);
+
+ // We need to read the default value first to read the environment variable.
+ llvm::SmallVector<llvm::StringRef> urls = llvm::getDefaultDebuginfodUrls();
+ Args arg_urls{urls};
+ m_collection_sp->SetPropertyAtIndexFromArgs(ePropertyServerURLs, arg_urls);
+
+ m_collection_sp->SetValueChangedCallback(
+ ePropertyServerURLs, [this] { ServerURLsChangedCallback(); });
+ }
+
+ Args GetDebugInfoDURLs() const {
+ Args urls;
+ m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyServerURLs, urls);
+ return urls;
+ }
+
+private:
+ void ServerURLsChangedCallback() {
+ m_server_urls = GetDebugInfoDURLs();
+ llvm::SmallVector<llvm::StringRef> dbginfod_urls;
+ llvm::for_each(m_server_urls, [&](const auto &obj) {
+ dbginfod_urls.push_back(obj.ref());
+ });
+ llvm::setDefaultDebuginfodUrls(dbginfod_urls);
+ }
+ // Storage for the StringRef's used within the Debuginfod library.
+ Args m_server_urls;
+};
+
+} // namespace
+
+static PluginProperties &GetGlobalPluginProperties() {
+ static PluginProperties g_settings;
+ return g_settings;
+}
+
+SymbolLocatorDebuginfod::SymbolLocatorDebuginfod() : SymbolLocator() {}
+
+void SymbolLocatorDebuginfod::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
+ LocateExecutableObjectFile, LocateExecutableSymbolFile, nullptr,
+ nullptr, SymbolLocatorDebuginfod::DebuggerInitialize);
+ llvm::HTTPClient::initialize();
+ });
+}
+
+void SymbolLocatorDebuginfod::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForSymbolLocatorPlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForSymbolLocatorPlugin(
+ debugger, GetGlobalPluginProperties().GetValueProperties(),
+ "Properties for the Debuginfod Symbol Locator plug-in.",
+ is_global_setting);
+ }
+}
+
+void SymbolLocatorDebuginfod::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+ llvm::HTTPClient::cleanup();
+}
+
+llvm::StringRef SymbolLocatorDebuginfod::GetPluginDescriptionStatic() {
+ return "Debuginfod symbol locator.";
+}
+
+SymbolLocator *SymbolLocatorDebuginfod::CreateInstance() {
+ return new SymbolLocatorDebuginfod();
+}
+
+static std::optional<FileSpec> GetFileForModule(
+ const ModuleSpec &module_spec,
+ std::function<llvm::Expected<std::string>(llvm::object::BuildIDRef)>
+ PullFromServer) {
+ if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup())
+ return {};
+ const UUID &module_uuid = module_spec.GetUUID();
+ if (module_uuid.IsValid() && llvm::canUseDebuginfod()) {
+ llvm::object::BuildID build_id(module_uuid.GetBytes());
+ llvm::Expected<std::string> result = PullFromServer(build_id);
+ if (result)
+ return FileSpec(*result);
+ // An error here should be logged as a failure in the Debuginfod library,
+ // so just consume it here
+ consumeError(result.takeError());
+ }
+ return {};
+}
+
+std::optional<ModuleSpec> SymbolLocatorDebuginfod::LocateExecutableObjectFile(
+ const ModuleSpec &module_spec) {
+ return GetFileForModule(module_spec, llvm::getCachedOrDownloadExecutable);
+}
+
+std::optional<FileSpec> SymbolLocatorDebuginfod::LocateExecutableSymbolFile(
+ const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
+ return GetFileForModule(module_spec, llvm::getCachedOrDownloadDebuginfo);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h
new file mode 100644
index 000000000000..0ea79fa1df2a
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h
@@ -0,0 +1,54 @@
+//===-- SymbolLocatorDebuginfod.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_SYMBOLLOCATOR_DEBUGINFOD_SYMBOLLOCATORDEBUGINFOD_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGINFOD_SYMBOLLOCATORDEBUGINFOD_H
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Symbol/SymbolLocator.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class SymbolLocatorDebuginfod : public SymbolLocator {
+public:
+ SymbolLocatorDebuginfod();
+
+ static void Initialize();
+ static void Terminate();
+ static void DebuggerInitialize(Debugger &debugger);
+
+ static llvm::StringRef GetPluginNameStatic() { return "debuginfod"; }
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolLocator *CreateInstance();
+
+ /// PluginInterface protocol.
+ /// \{
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+ /// \}
+
+ // Locate the executable file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using the
+ // current computers global settings.
+ static std::optional<ModuleSpec>
+ LocateExecutableObjectFile(const ModuleSpec &module_spec);
+
+ // Locate the symbol file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using the
+ // current computers global settings.
+ static std::optional<FileSpec>
+ LocateExecutableSymbolFile(const ModuleSpec &module_spec,
+ const FileSpecList &default_search_paths);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGINFOD_SYMBOLLOCATORDEBUGINFOD_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td
new file mode 100644
index 000000000000..1c668b001a16
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td
@@ -0,0 +1,7 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "symbollocatordebuginfod" in {
+ def ServerURLs : Property<"server_urls", "Array">,
+ ElementType<"String">,
+ Desc<"An ordered list of Debuginfod server URLs to query for symbols. This defaults to the contents of the DEBUGINFOD_URLS environment variable.">;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.cpp
new file mode 100644
index 000000000000..ed014f99fdb5
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.cpp
@@ -0,0 +1,239 @@
+//===-- SymbolLocatorDefault.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 "SymbolLocatorDefault.h"
+
+#include <cstring>
+#include <optional>
+
+#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+#include "lldb/Utility/UUID.h"
+
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/ThreadPool.h"
+
+// From MacOSX system header "mach/machine.h"
+typedef int cpu_type_t;
+typedef int cpu_subtype_t;
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(SymbolLocatorDefault)
+
+SymbolLocatorDefault::SymbolLocatorDefault() : SymbolLocator() {}
+
+void SymbolLocatorDefault::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
+ LocateExecutableObjectFile, LocateExecutableSymbolFile,
+ DownloadObjectAndSymbolFile);
+}
+
+void SymbolLocatorDefault::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+llvm::StringRef SymbolLocatorDefault::GetPluginDescriptionStatic() {
+ return "Default symbol locator.";
+}
+
+SymbolLocator *SymbolLocatorDefault::CreateInstance() {
+ return new SymbolLocatorDefault();
+}
+
+std::optional<ModuleSpec> SymbolLocatorDefault::LocateExecutableObjectFile(
+ const ModuleSpec &module_spec) {
+ const FileSpec &exec_fspec = module_spec.GetFileSpec();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+ const UUID *uuid = module_spec.GetUUIDPtr();
+ LLDB_SCOPED_TIMERF(
+ "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
+ exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>",
+ arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
+
+ ModuleSpecList module_specs;
+ ModuleSpec matched_module_spec;
+ if (exec_fspec &&
+ ObjectFile::GetModuleSpecifications(exec_fspec, 0, 0, module_specs) &&
+ module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) {
+ ModuleSpec result;
+ result.GetFileSpec() = exec_fspec;
+ return result;
+ }
+
+ return {};
+}
+
+// Keep "symbols.enable-external-lookup" description in sync with this function.
+std::optional<FileSpec> SymbolLocatorDefault::LocateExecutableSymbolFile(
+ const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
+
+ FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
+ if (symbol_file_spec.IsAbsolute() &&
+ FileSystem::Instance().Exists(symbol_file_spec))
+ return symbol_file_spec;
+
+ Progress progress(llvm::formatv(
+ "Locating external symbol file for {0}",
+ module_spec.GetFileSpec().GetFilename().AsCString("<Unknown>")));
+
+ FileSpecList debug_file_search_paths = default_search_paths;
+
+ // Add module directory.
+ FileSpec module_file_spec = module_spec.GetFileSpec();
+ // We keep the unresolved pathname if it fails.
+ FileSystem::Instance().ResolveSymbolicLink(module_file_spec,
+ module_file_spec);
+
+ ConstString file_dir = module_file_spec.GetDirectory();
+ {
+ FileSpec file_spec(file_dir.AsCString("."));
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+
+ if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+
+ // Add current working directory.
+ {
+ FileSpec file_spec(".");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+
+#ifndef _WIN32
+#if defined(__NetBSD__)
+ // Add /usr/libdata/debug directory.
+ {
+ FileSpec file_spec("/usr/libdata/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+#else
+ // Add /usr/lib/debug directory.
+ {
+ FileSpec file_spec("/usr/lib/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+#endif
+#endif // _WIN32
+ }
+
+ std::string uuid_str;
+ const UUID &module_uuid = module_spec.GetUUID();
+ if (module_uuid.IsValid()) {
+ // Some debug files are stored in the .build-id directory like this:
+ // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
+ uuid_str = module_uuid.GetAsString("");
+ std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
+ ::tolower);
+ uuid_str.insert(2, 1, '/');
+ uuid_str = uuid_str + ".debug";
+ }
+
+ size_t num_directories = debug_file_search_paths.GetSize();
+ for (size_t idx = 0; idx < num_directories; ++idx) {
+ FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+ FileSystem::Instance().Resolve(dirspec);
+ if (!FileSystem::Instance().IsDirectory(dirspec))
+ continue;
+
+ std::vector<std::string> files;
+ std::string dirname = dirspec.GetPath();
+
+ if (!uuid_str.empty())
+ files.push_back(dirname + "/.build-id/" + uuid_str);
+ if (symbol_file_spec.GetFilename()) {
+ files.push_back(dirname + "/" +
+ symbol_file_spec.GetFilename().GetCString());
+ files.push_back(dirname + "/.debug/" +
+ symbol_file_spec.GetFilename().GetCString());
+
+ // Some debug files may stored in the module directory like this:
+ // /usr/lib/debug/usr/lib/library.so.debug
+ if (!file_dir.IsEmpty())
+ files.push_back(dirname + file_dir.AsCString() + "/" +
+ symbol_file_spec.GetFilename().GetCString());
+ }
+
+ const uint32_t num_files = files.size();
+ for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
+ const std::string &filename = files[idx_file];
+ FileSpec file_spec(filename);
+ FileSystem::Instance().Resolve(file_spec);
+
+ if (llvm::sys::fs::equivalent(file_spec.GetPath(),
+ module_file_spec.GetPath()))
+ continue;
+
+ if (FileSystem::Instance().Exists(file_spec)) {
+ lldb_private::ModuleSpecList specs;
+ const size_t num_specs =
+ ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
+ ModuleSpec mspec;
+ bool valid_mspec = false;
+ if (num_specs == 2) {
+ // Special case to handle both i386 and i686 from ObjectFilePECOFF
+ ModuleSpec mspec2;
+ if (specs.GetModuleSpecAtIndex(0, mspec) &&
+ specs.GetModuleSpecAtIndex(1, mspec2) &&
+ mspec.GetArchitecture().GetTriple().isCompatibleWith(
+ mspec2.GetArchitecture().GetTriple())) {
+ valid_mspec = true;
+ }
+ }
+ if (!valid_mspec) {
+ assert(num_specs <= 1 &&
+ "Symbol Vendor supports only a single architecture");
+ if (num_specs == 1) {
+ if (specs.GetModuleSpecAtIndex(0, mspec)) {
+ valid_mspec = true;
+ }
+ }
+ }
+ if (valid_mspec) {
+ // Skip the uuids check if module_uuid is invalid. For example,
+ // this happens for *.dwp files since at the moment llvm-dwp
+ // doesn't output build ids, nor does binutils dwp.
+ if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
+ return file_spec;
+ }
+ }
+ }
+ }
+
+ return {};
+}
+
+bool SymbolLocatorDefault::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+ Status &error,
+ bool force_lookup,
+ bool copy_executable) {
+ return false;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.h b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.h
new file mode 100644
index 000000000000..7bf0a2ad4a5b
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.h
@@ -0,0 +1,64 @@
+//===-- SymbolLocatorDefault.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_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H
+
+#include "lldb/Symbol/SymbolLocator.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class SymbolLocatorDefault : public SymbolLocator {
+public:
+ SymbolLocatorDefault();
+
+ static void Initialize();
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "Default"; }
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolLocator *CreateInstance();
+
+ /// PluginInterface protocol.
+ /// \{
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+ /// \}
+
+ // Locate the executable file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using the
+ // current computers global settings.
+ static std::optional<ModuleSpec>
+ LocateExecutableObjectFile(const ModuleSpec &module_spec);
+
+ // Locate the symbol file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using the
+ // current computers global settings.
+ static std::optional<FileSpec>
+ LocateExecutableSymbolFile(const ModuleSpec &module_spec,
+ const FileSpecList &default_search_paths);
+
+ // Locate the object and symbol file given a module specification.
+ //
+ // Locating the file can try to download the file from a corporate build
+ // repository, or using any other means necessary to locate both the
+ // unstripped object file and the debug symbols. The force_lookup argument
+ // controls whether the external program is called unconditionally to find
+ // the symbol file, or if the user's settings are checked to see if they've
+ // enabled the external program before calling.
+ static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+ Status &error, bool force_lookup,
+ bool copy_executable);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H
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 55a663bb1b96..b5fe35d71032 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -16,7 +16,6 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
-#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StreamString.h"
@@ -87,7 +86,7 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
module_spec.GetUUID() = uuid;
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec dsym_fspec =
- Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+ PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
if (!dsym_fspec)
return nullptr;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp
index 0f8d3108998d..6393363db51f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp
@@ -16,7 +16,6 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
-#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StreamString.h"
@@ -87,7 +86,7 @@ SymbolVendorPECOFF::CreateInstance(const lldb::ModuleSP &module_sp,
module_spec.GetUUID() = uuid;
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec dsym_fspec =
- Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+ PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
if (!dsym_fspec)
return nullptr;
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 91b10ea64535..f8a9389c0ff9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
@@ -17,7 +17,6 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
-#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StreamString.h"
@@ -87,7 +86,7 @@ SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec sym_fspec =
- Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+ PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
if (!sym_fspec)
return nullptr;
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 254baaf3e673..82714dea3fcd 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
@@ -105,7 +105,7 @@ public:
Options *GetOptions() override { return &m_options; }
protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override;
+ void DoExecute(Args &command, CommandReturnObject &result) override;
TraceIntelPT &m_trace;
CommandOptions m_options;
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 bcac731713bb..72e9948ffe81 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
@@ -48,8 +48,8 @@ enum {
#include "TraceIntelPTPropertiesEnum.inc"
};
-ConstString TraceIntelPT::PluginProperties::GetSettingName() {
- return ConstString(TraceIntelPT::GetPluginNameStatic());
+llvm::StringRef TraceIntelPT::PluginProperties::GetSettingName() {
+ return TraceIntelPT::GetPluginNameStatic();
}
TraceIntelPT::PluginProperties::PluginProperties() : Properties() {
@@ -60,14 +60,14 @@ TraceIntelPT::PluginProperties::PluginProperties() : Properties() {
uint64_t
TraceIntelPT::PluginProperties::GetInfiniteDecodingLoopVerificationThreshold() {
const uint32_t idx = ePropertyInfiniteDecodingLoopVerificationThreshold;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_traceintelpt_properties[idx].default_uint_value);
+ return GetPropertyAtIndexAs<uint64_t>(
+ idx, g_traceintelpt_properties[idx].default_uint_value);
}
uint64_t TraceIntelPT::PluginProperties::GetExtremelyLargeDecodingThreshold() {
const uint32_t idx = ePropertyExtremelyLargeDecodingThreshold;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_traceintelpt_properties[idx].default_uint_value);
+ return GetPropertyAtIndexAs<uint64_t>(
+ idx, g_traceintelpt_properties[idx].default_uint_value);
}
TraceIntelPT::PluginProperties &TraceIntelPT::GetGlobalProperties() {
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 20faabdce790..da9cefe9ed95 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
@@ -26,7 +26,7 @@ public:
/// Properties to be used with the `settings` command.
class PluginProperties : public Properties {
public:
- static ConstString GetSettingName();
+ static llvm::StringRef GetSettingName();
PluginProperties();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp
index e183e592986a..bd9cca675f2d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTBundleLoader.cpp
@@ -103,10 +103,11 @@ TraceIntelPTBundleLoader::CreateEmptyProcess(lldb::pid_t pid,
ParsedProcess parsed_process;
parsed_process.target_sp = target_sp;
- ProcessSP process_sp = target_sp->CreateProcess(
- /*listener*/ nullptr, "trace",
- /*crash_file*/ nullptr,
- /*can_connect*/ false);
+ // This should instead try to directly create an instance of ProcessTrace.
+ // ProcessSP process_sp = target_sp->CreateProcess(
+ // /*listener*/ nullptr, "trace",
+ // /*crash_file*/ nullptr,
+ // /*can_connect*/ false);
process_sp->SetID(static_cast<lldb::pid_t>(pid));
@@ -285,7 +286,7 @@ StringRef TraceIntelPTBundleLoader::GetSchema() {
"tscPerfZeroConversion"?: {
// Values used to convert between TSCs and nanoseconds. See the time_zero
// section in https://man7.org/linux/man-pages/man2/perf_event_open.2.html
- // for for information.
+ // for information.
"timeMult": integer,
"timeShift": integer,
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
index 33d05ee2ac13..ee8970fb4de2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
@@ -62,7 +62,7 @@ CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() {
return llvm::ArrayRef(g_thread_trace_export_ctf_options);
}
-bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
+void CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
CommandReturnObject &result) {
const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
Process *process = m_exe_ctx.GetProcessPtr();
@@ -78,7 +78,6 @@ bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
result.AppendErrorWithFormatv(
"Thread index {0} is out of range (valid values are 1 - {1}).\n", tid,
num_threads);
- return false;
} else {
auto do_work = [&]() -> Error {
Expected<TraceCursorSP> cursor = trace_sp->CreateNewCursor(*thread);
@@ -91,9 +90,6 @@ bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
if (llvm::Error err = do_work()) {
result.AppendErrorWithFormat("%s\n", toString(std::move(err)).c_str());
- return false;
- } else {
- return true;
}
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
index c9f02a372ded..1a034e87cfb6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
@@ -48,7 +48,7 @@ public:
Options *GetOptions() override { return &m_options; }
protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override;
+ void DoExecute(Args &command, CommandReturnObject &result) override;
CommandOptions m_options;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst
index 1341cf5f0c80..beee14dce25a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst
+++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst
@@ -21,7 +21,7 @@ Concepts
**Pass:** A transformation applied to a *layer* that generates a new *layer* that is a more summarized, consolidated representation of the trace data.
A pass merges instructions/blocks based on its specific purpose - for example, a pass designed to summarize a processor trace by function calls would merge all the blocks of a function into a single block representing the entire function.
-The image below illusrates the transformation of a trace's representation (HTR)
+The image below illustrates the transformation of a trace's representation (HTR)
.. image:: media/htr-example.png
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 c7430882adb5..503cbedce982 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -56,8 +56,8 @@
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Host/StreamFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/ExecutionContext.h"
@@ -86,6 +86,7 @@
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
+using namespace lldb_private::plugin::dwarf;
using namespace clang;
using llvm::StringSwitch;
@@ -2293,12 +2294,13 @@ CompilerType TypeSystemClang::CreateArrayType(const CompilerType &element_type,
llvm::APInt ap_element_count(64, element_count);
if (element_count == 0) {
- return GetType(ast.getIncompleteArrayType(
- ClangUtil::GetQualType(element_type), clang::ArrayType::Normal, 0));
+ return GetType(
+ ast.getIncompleteArrayType(ClangUtil::GetQualType(element_type),
+ clang::ArraySizeModifier::Normal, 0));
} else {
return GetType(ast.getConstantArrayType(
ClangUtil::GetQualType(element_type), ap_element_count, nullptr,
- clang::ArrayType::Normal, 0));
+ clang::ArraySizeModifier::Normal, 0));
}
}
}
@@ -2318,8 +2320,9 @@ CompilerType TypeSystemClang::CreateStructForIdentifier(
return type;
}
- type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
- type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
+ type = CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, type_name,
+ llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
StartTagDeclarationDefinition(type);
for (const auto &field : type_fields)
AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
@@ -2458,89 +2461,6 @@ void TypeSystemClang::DumpDeclHiearchy(clang::Decl *decl) {
}
}
-bool TypeSystemClang::DeclsAreEquivalent(clang::Decl *lhs_decl,
- clang::Decl *rhs_decl) {
- if (lhs_decl && rhs_decl) {
- // Make sure the decl kinds match first
- const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
- const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
-
- if (lhs_decl_kind == rhs_decl_kind) {
- // Now check that the decl contexts kinds are all equivalent before we
- // have to check any names of the decl contexts...
- clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
- clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
- if (lhs_decl_ctx && rhs_decl_ctx) {
- while (true) {
- if (lhs_decl_ctx && rhs_decl_ctx) {
- const clang::Decl::Kind lhs_decl_ctx_kind =
- lhs_decl_ctx->getDeclKind();
- const clang::Decl::Kind rhs_decl_ctx_kind =
- rhs_decl_ctx->getDeclKind();
- if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
- lhs_decl_ctx = lhs_decl_ctx->getParent();
- rhs_decl_ctx = rhs_decl_ctx->getParent();
-
- if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
- break;
- } else
- return false;
- } else
- return false;
- }
-
- // Now make sure the name of the decls match
- clang::NamedDecl *lhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
- clang::NamedDecl *rhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
- if (lhs_named_decl && rhs_named_decl) {
- clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
- clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
- if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
- if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
- return false;
- } else
- return false;
- } else
- return false;
-
- // We know that the decl context kinds all match, so now we need to
- // make sure the names match as well
- lhs_decl_ctx = lhs_decl->getDeclContext();
- rhs_decl_ctx = rhs_decl->getDeclContext();
- while (true) {
- switch (lhs_decl_ctx->getDeclKind()) {
- case clang::Decl::TranslationUnit:
- // We don't care about the translation unit names
- return true;
- default: {
- clang::NamedDecl *lhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
- clang::NamedDecl *rhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
- if (lhs_named_decl && rhs_named_decl) {
- clang::DeclarationName lhs_decl_name =
- lhs_named_decl->getDeclName();
- clang::DeclarationName rhs_decl_name =
- rhs_named_decl->getDeclName();
- if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
- if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
- return false;
- } else
- return false;
- } else
- return false;
- } break;
- }
- lhs_decl_ctx = lhs_decl_ctx->getParent();
- rhs_decl_ctx = rhs_decl_ctx->getParent();
- }
- }
- }
- }
- return false;
-}
bool TypeSystemClang::GetCompleteDecl(clang::ASTContext *ast,
clang::Decl *decl) {
if (!decl)
@@ -2636,6 +2556,13 @@ TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
return GetDeclContextForType(ClangUtil::GetQualType(type));
}
+CompilerDeclContext
+TypeSystemClang::GetCompilerDeclContextForType(const CompilerType &type) {
+ if (auto *decl_context = GetDeclContextForType(type))
+ return CreateDeclContext(decl_context);
+ return CompilerDeclContext();
+}
+
/// Aggressively desugar the provided type, skipping past various kinds of
/// syntactic sugar and other constructs one typically wants to ignore.
/// The \p mask argument allows one to skip certain kinds of simplifications,
@@ -3549,8 +3476,15 @@ bool TypeSystemClang::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
if (record_decl) {
const clang::CXXRecordDecl *cxx_record_decl =
llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- return cxx_record_decl->isPolymorphic();
+ if (cxx_record_decl) {
+ // We can't just call is isPolymorphic() here because that just
+ // means the current class has virtual functions, it doesn't check
+ // if any inherited classes have virtual functions. The doc string
+ // in SBType::IsPolymorphicClass() says it is looking for both
+ // if the class has virtual methods or if any bases do, so this
+ // should be more correct.
+ return cxx_record_decl->isDynamicClass();
+ }
}
}
break;
@@ -4293,10 +4227,10 @@ CompilerType TypeSystemClang::GetArrayType(lldb::opaque_compiler_type_t type,
if (size != 0)
return GetType(ast_ctx.getConstantArrayType(
qual_type, llvm::APInt(64, size), nullptr,
- clang::ArrayType::ArraySizeModifier::Normal, 0));
+ clang::ArraySizeModifier::Normal, 0));
else
return GetType(ast_ctx.getIncompleteArrayType(
- qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0));
+ qual_type, clang::ArraySizeModifier::Normal, 0));
}
return CompilerType();
@@ -4700,6 +4634,21 @@ TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) {
CompilerType TypeSystemClang::GetBasicTypeFromAST(lldb::BasicType basic_type) {
return TypeSystemClang::GetBasicType(basic_type);
}
+
+CompilerType TypeSystemClang::CreateGenericFunctionPrototype() {
+ clang::ASTContext &ast = getASTContext();
+ const FunctionType::ExtInfo generic_ext_info(
+ /*noReturn=*/false,
+ /*hasRegParm=*/false,
+ /*regParm=*/0,
+ CallingConv::CC_C,
+ /*producesResult=*/false,
+ /*noCallerSavedRegs=*/false,
+ /*NoCfCheck=*/false,
+ /*cmseNSCall=*/false);
+ QualType func_type = ast.getFunctionNoProtoType(ast.VoidTy, generic_ext_info);
+ return GetType(func_type);
+}
// Exploring the type
const llvm::fltSemantics &
@@ -4816,7 +4765,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::Type::FunctionNoProto:
case clang::Type::FunctionProto:
- break;
+ return lldb::eEncodingUint;
case clang::Type::IncompleteArray:
case clang::Type::VariableArray:
@@ -5361,11 +5310,8 @@ uint32_t TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type,
num_children += cxx_record_decl->getNumBases();
}
}
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(),
- field_end = record_decl->field_end();
- field != field_end; ++field)
- ++num_children;
+ num_children += std::distance(record_decl->field_begin(),
+ record_decl->field_end());
}
break;
@@ -5576,13 +5522,8 @@ uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type) {
if (record_type) {
clang::RecordDecl *record_decl = record_type->getDecl();
if (record_decl) {
- uint32_t field_idx = 0;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(),
- field_end = record_decl->field_end();
- field != field_end; ++field)
- ++field_idx;
- count = field_idx;
+ count = std::distance(record_decl->field_begin(),
+ record_decl->field_end());
}
}
}
@@ -7183,7 +7124,8 @@ GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl,
// (including the ones preceding the parameter pack).
const auto &pack = args[last_idx];
const size_t pack_idx = idx - last_idx;
- assert(pack_idx < pack.pack_size() && "parameter pack index out-of-bounds");
+ if (pack_idx >= pack.pack_size())
+ return nullptr;
return &pack.pack_elements()[pack_idx];
}
@@ -7651,7 +7593,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
nullptr /*expr*/, is_explicit ? clang::ExplicitSpecKind::ResolvedTrue
: clang::ExplicitSpecKind::ResolvedFalse);
- if (name.startswith("~")) {
+ if (name.starts_with("~")) {
cxx_dtor_decl =
clang::CXXDestructorDecl::CreateDeserialized(getASTContext(), 0);
cxx_dtor_decl->setDeclContext(cxx_record_decl);
@@ -7986,8 +7928,8 @@ bool TypeSystemClang::AddObjCClassProperty(
const bool isSynthesizedAccessorStub = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
- const clang::ObjCMethodDecl::ImplementationControl impControl =
- clang::ObjCMethodDecl::None;
+ const clang::ObjCImplementationControl impControl =
+ clang::ObjCImplementationControl::None;
const bool HasRelatedResultType = false;
getter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0);
@@ -8028,8 +7970,8 @@ bool TypeSystemClang::AddObjCClassProperty(
const bool isSynthesizedAccessorStub = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
- const clang::ObjCMethodDecl::ImplementationControl impControl =
- clang::ObjCMethodDecl::None;
+ const clang::ObjCImplementationControl impControl =
+ clang::ObjCImplementationControl::None;
const bool HasRelatedResultType = false;
setter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0);
@@ -8085,8 +8027,8 @@ clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
const char *name, // the full symbol name as seen in the symbol table
// (lldb::opaque_compiler_type_t type, "-[NString
// stringWithCString:]")
- const CompilerType &method_clang_type, lldb::AccessType access,
- bool is_artificial, bool is_variadic, bool is_objc_direct_call) {
+ const CompilerType &method_clang_type, bool is_artificial, bool is_variadic,
+ bool is_objc_direct_call) {
if (!type || !method_clang_type.IsValid())
return nullptr;
@@ -8150,8 +8092,8 @@ clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
/// Force this to true because we don't have source locations.
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
- const clang::ObjCMethodDecl::ImplementationControl impControl =
- clang::ObjCMethodDecl::None;
+ const clang::ObjCImplementationControl impControl =
+ clang::ObjCImplementationControl::None;
const bool HasRelatedResultType = false;
const unsigned num_args = method_function_prototype->getNumParams();
@@ -8520,380 +8462,6 @@ void TypeSystemClang::DumpFromSymbolFile(Stream &s,
}
}
-void TypeSystemClang::DumpValue(
- lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream &s,
- lldb::Format format, const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_offset, size_t data_byte_size,
- uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
- bool show_summary, bool verbose, uint32_t depth) {
- if (!type)
- return;
-
- clang::QualType qual_type(GetQualType(type));
- switch (qual_type->getTypeClass()) {
- case clang::Type::Record:
- if (GetCompleteType(type)) {
- const clang::RecordType *record_type =
- llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- uint32_t field_bit_offset = 0;
- uint32_t field_byte_offset = 0;
- const clang::ASTRecordLayout &record_layout =
- getASTContext().getASTRecordLayout(record_decl);
- uint32_t child_idx = 0;
-
- const clang::CXXRecordDecl *cxx_record_decl =
- llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl) {
- // We might have base classes to print out first
- clang::CXXRecordDecl::base_class_const_iterator base_class,
- base_class_end;
- for (base_class = cxx_record_decl->bases_begin(),
- base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end; ++base_class) {
- const clang::CXXRecordDecl *base_class_decl =
- llvm::cast<clang::CXXRecordDecl>(
- base_class->getType()->getAs<clang::RecordType>()->getDecl());
-
- // Skip empty base classes
- if (!verbose && !TypeSystemClang::RecordHasFields(base_class_decl))
- continue;
-
- if (base_class->isVirtual())
- field_bit_offset =
- record_layout.getVBaseClassOffset(base_class_decl)
- .getQuantity() *
- 8;
- else
- field_bit_offset = record_layout.getBaseClassOffset(base_class_decl)
- .getQuantity() *
- 8;
- field_byte_offset = field_bit_offset / 8;
- assert(field_bit_offset % 8 == 0);
- if (child_idx == 0)
- s.PutChar('{');
- else
- s.PutChar(',');
-
- clang::QualType base_class_qual_type = base_class->getType();
- std::string base_class_type_name(base_class_qual_type.getAsString());
-
- // Indent and print the base class type name
- s.Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT),
- base_class_type_name);
-
- clang::TypeInfo base_class_type_info =
- getASTContext().getTypeInfo(base_class_qual_type);
-
- // Dump the value of the member
- CompilerType base_clang_type = GetType(base_class_qual_type);
- base_clang_type.DumpValue(
- exe_ctx,
- &s, // Stream to dump to
- base_clang_type
- .GetFormat(), // The format with which to display the member
- data, // Data buffer containing all bytes for this type
- data_byte_offset + field_byte_offset, // Offset into "data" where
- // to grab value from
- base_class_type_info.Width / 8, // Size of this type in bytes
- 0, // Bitfield bit size
- 0, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable
- // types
- show_summary, // Boolean indicating if we should show a summary
- // for the current type
- verbose, // Verbose output?
- depth + DEPTH_INCREMENT); // Scope depth for any types that have
- // children
-
- ++child_idx;
- }
- }
- uint32_t field_idx = 0;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(),
- field_end = record_decl->field_end();
- field != field_end; ++field, ++field_idx, ++child_idx) {
- // Print the starting squiggly bracket (if this is the first member) or
- // comma (for member 2 and beyond) for the struct/union/class member.
- if (child_idx == 0)
- s.PutChar('{');
- else
- s.PutChar(',');
-
- // Indent
- s.Printf("\n%*s", depth + DEPTH_INCREMENT, "");
-
- clang::QualType field_type = field->getType();
- // Print the member type if requested
- // Figure out the type byte size (field_type_info.first) and alignment
- // (field_type_info.second) from the AST context.
- clang::TypeInfo field_type_info =
- getASTContext().getTypeInfo(field_type);
- assert(field_idx < record_layout.getFieldCount());
- // Figure out the field offset within the current struct/union/class
- // type
- field_bit_offset = record_layout.getFieldOffset(field_idx);
- field_byte_offset = field_bit_offset / 8;
- uint32_t field_bitfield_bit_size = 0;
- uint32_t field_bitfield_bit_offset = 0;
- if (FieldIsBitfield(*field, field_bitfield_bit_size))
- field_bitfield_bit_offset = field_bit_offset % 8;
-
- if (show_types) {
- std::string field_type_name(field_type.getAsString());
- if (field_bitfield_bit_size > 0)
- s.Printf("(%s:%u) ", field_type_name.c_str(),
- field_bitfield_bit_size);
- else
- s.Printf("(%s) ", field_type_name.c_str());
- }
- // Print the member name and equal sign
- s.Printf("%s = ", field->getNameAsString().c_str());
-
- // Dump the value of the member
- CompilerType field_clang_type = GetType(field_type);
- field_clang_type.DumpValue(
- exe_ctx,
- &s, // Stream to dump to
- field_clang_type
- .GetFormat(), // The format with which to display the member
- data, // Data buffer containing all bytes for this type
- data_byte_offset + field_byte_offset, // Offset into "data" where to
- // grab value from
- field_type_info.Width / 8, // Size of this type in bytes
- field_bitfield_bit_size, // Bitfield bit size
- field_bitfield_bit_offset, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable
- // types
- show_summary, // Boolean indicating if we should show a summary for
- // the current type
- verbose, // Verbose output?
- depth + DEPTH_INCREMENT); // Scope depth for any types that have
- // children
- }
-
- // Indent the trailing squiggly bracket
- if (child_idx > 0)
- s.Printf("\n%*s}", depth, "");
- }
- return;
-
- case clang::Type::Enum:
- if (GetCompleteType(type)) {
- const clang::EnumType *enutype =
- llvm::cast<clang::EnumType>(qual_type.getTypePtr());
- const clang::EnumDecl *enum_decl = enutype->getDecl();
- assert(enum_decl);
- clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
- lldb::offset_t offset = data_byte_offset;
- const int64_t enum_value = data.GetMaxU64Bitfield(
- &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
- for (enum_pos = enum_decl->enumerator_begin(),
- enum_end_pos = enum_decl->enumerator_end();
- enum_pos != enum_end_pos; ++enum_pos) {
- if (enum_pos->getInitVal() == enum_value) {
- s.Printf("%s", enum_pos->getNameAsString().c_str());
- return;
- }
- }
- // If we have gotten here we didn't get find the enumerator in the enum
- // decl, so just print the integer.
- s.Printf("%" PRIi64, enum_value);
- }
- return;
-
- case clang::Type::ConstantArray: {
- const clang::ConstantArrayType *array =
- llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
- bool is_array_of_characters = false;
- clang::QualType element_qual_type = array->getElementType();
-
- const clang::Type *canonical_type =
- element_qual_type->getCanonicalTypeInternal().getTypePtr();
- if (canonical_type)
- is_array_of_characters = canonical_type->isCharType();
-
- const uint64_t element_count = array->getSize().getLimitedValue();
-
- clang::TypeInfo field_type_info =
- getASTContext().getTypeInfo(element_qual_type);
-
- uint32_t element_idx = 0;
- uint32_t element_offset = 0;
- uint64_t element_byte_size = field_type_info.Width / 8;
- uint32_t element_stride = element_byte_size;
-
- if (is_array_of_characters) {
- s.PutChar('"');
- DumpDataExtractor(data, &s, data_byte_offset, lldb::eFormatChar,
- element_byte_size, element_count, UINT32_MAX,
- LLDB_INVALID_ADDRESS, 0, 0);
- s.PutChar('"');
- return;
- } else {
- CompilerType element_clang_type = GetType(element_qual_type);
- lldb::Format element_format = element_clang_type.GetFormat();
-
- for (element_idx = 0; element_idx < element_count; ++element_idx) {
- // Print the starting squiggly bracket (if this is the first member) or
- // comman (for member 2 and beyong) for the struct/union/class member.
- if (element_idx == 0)
- s.PutChar('{');
- else
- s.PutChar(',');
-
- // Indent and print the index
- s.Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
-
- // Figure out the field offset within the current struct/union/class
- // type
- element_offset = element_idx * element_stride;
-
- // Dump the value of the member
- element_clang_type.DumpValue(
- exe_ctx,
- &s, // Stream to dump to
- element_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset +
- element_offset, // Offset into "data" where to grab value from
- element_byte_size, // Size of this type in bytes
- 0, // Bitfield bit size
- 0, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable
- // types
- show_summary, // Boolean indicating if we should show a summary for
- // the current type
- verbose, // Verbose output?
- depth + DEPTH_INCREMENT); // Scope depth for any types that have
- // children
- }
-
- // Indent the trailing squiggly bracket
- if (element_idx > 0)
- s.Printf("\n%*s}", depth, "");
- }
- }
- return;
-
- case clang::Type::Typedef: {
- clang::QualType typedef_qual_type =
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType();
-
- CompilerType typedef_clang_type = GetType(typedef_qual_type);
- lldb::Format typedef_format = typedef_clang_type.GetFormat();
- clang::TypeInfo typedef_type_info =
- getASTContext().getTypeInfo(typedef_qual_type);
- uint64_t typedef_byte_size = typedef_type_info.Width / 8;
-
- return typedef_clang_type.DumpValue(
- exe_ctx,
- &s, // Stream to dump to
- typedef_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset, // Offset into "data" where to grab value from
- typedef_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Bitfield bit size
- bitfield_bit_offset, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the
- // current type
- verbose, // Verbose output?
- depth); // Scope depth for any types that have children
- } break;
-
- case clang::Type::Auto: {
- clang::QualType elaborated_qual_type =
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType();
- CompilerType elaborated_clang_type = GetType(elaborated_qual_type);
- lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
- clang::TypeInfo elaborated_type_info =
- getASTContext().getTypeInfo(elaborated_qual_type);
- uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
-
- return elaborated_clang_type.DumpValue(
- exe_ctx,
- &s, // Stream to dump to
- elaborated_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset, // Offset into "data" where to grab value from
- elaborated_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Bitfield bit size
- bitfield_bit_offset, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the
- // current type
- verbose, // Verbose output?
- depth); // Scope depth for any types that have children
- } break;
-
- case clang::Type::Elaborated: {
- clang::QualType elaborated_qual_type =
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
- CompilerType elaborated_clang_type = GetType(elaborated_qual_type);
- lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
- clang::TypeInfo elaborated_type_info =
- getASTContext().getTypeInfo(elaborated_qual_type);
- uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
-
- return elaborated_clang_type.DumpValue(
- exe_ctx,
- &s, // Stream to dump to
- elaborated_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset, // Offset into "data" where to grab value from
- elaborated_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Bitfield bit size
- bitfield_bit_offset, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the
- // current type
- verbose, // Verbose output?
- depth); // Scope depth for any types that have children
- } break;
-
- case clang::Type::Paren: {
- clang::QualType desugar_qual_type =
- llvm::cast<clang::ParenType>(qual_type)->desugar();
- CompilerType desugar_clang_type = GetType(desugar_qual_type);
-
- lldb::Format desugar_format = desugar_clang_type.GetFormat();
- clang::TypeInfo desugar_type_info =
- getASTContext().getTypeInfo(desugar_qual_type);
- uint64_t desugar_byte_size = desugar_type_info.Width / 8;
-
- return desugar_clang_type.DumpValue(
- exe_ctx,
- &s, // Stream to dump to
- desugar_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset, // Offset into "data" where to grab value from
- desugar_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Bitfield bit size
- bitfield_bit_offset, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the
- // current type
- verbose, // Verbose output?
- depth); // Scope depth for any types that have children
- } break;
-
- default:
- // We are down to a scalar type that we just need to display.
- DumpDataExtractor(data, &s, data_byte_offset, format, data_byte_size, 1,
- UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
- bitfield_bit_offset);
-
- if (show_summary)
- DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
- break;
- }
-}
-
static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s,
const DataExtractor &data, lldb::offset_t byte_offset,
size_t byte_size, uint32_t bitfield_bit_offset,
@@ -9099,51 +8667,6 @@ bool TypeSystemClang::DumpTypeValue(
return false;
}
-void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type,
- ExecutionContext *exe_ctx, Stream &s,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_offset,
- size_t data_byte_size) {
- uint32_t length = 0;
- if (IsCStringType(type, length)) {
- if (exe_ctx) {
- Process *process = exe_ctx->GetProcessPtr();
- if (process) {
- lldb::offset_t offset = data_byte_offset;
- lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
- std::vector<uint8_t> buf;
- if (length > 0)
- buf.resize(length);
- else
- buf.resize(256);
-
- DataExtractor cstr_data(&buf.front(), buf.size(),
- process->GetByteOrder(), 4);
- buf.back() = '\0';
- size_t bytes_read;
- size_t total_cstr_len = 0;
- Status error;
- while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(),
- buf.size(), error)) > 0) {
- const size_t len = strlen((const char *)&buf.front());
- if (len == 0)
- break;
- if (total_cstr_len == 0)
- s.PutCString(" \"");
- DumpDataExtractor(cstr_data, &s, 0, lldb::eFormatChar, 1, len,
- UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
- total_cstr_len += len;
- if (len < buf.size())
- break;
- pointer_address += total_cstr_len;
- }
- if (total_cstr_len > 0)
- s.PutChar('"');
- }
- }
- }
-}
-
void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
lldb::DescriptionLevel level) {
StreamFile s(stdout, false);
@@ -9468,6 +8991,66 @@ size_t TypeSystemClang::DeclGetFunctionNumArguments(void *opaque_decl) {
return 0;
}
+static CompilerContextKind GetCompilerKind(clang::Decl::Kind clang_kind,
+ clang::DeclContext const *decl_ctx) {
+ switch (clang_kind) {
+ case Decl::TranslationUnit:
+ return CompilerContextKind::TranslationUnit;
+ case Decl::Namespace:
+ return CompilerContextKind::Namespace;
+ case Decl::Var:
+ return CompilerContextKind::Variable;
+ case Decl::Enum:
+ return CompilerContextKind::Enum;
+ case Decl::Typedef:
+ return CompilerContextKind::Typedef;
+ default:
+ // Many other kinds have multiple values
+ if (decl_ctx) {
+ if (decl_ctx->isFunctionOrMethod())
+ return CompilerContextKind::Function;
+ else if (decl_ctx->isRecord())
+ return (CompilerContextKind)((uint16_t)CompilerContextKind::Class |
+ (uint16_t)CompilerContextKind::Struct |
+ (uint16_t)CompilerContextKind::Union);
+ }
+ break;
+ }
+ return CompilerContextKind::Any;
+}
+
+static void
+InsertCompilerContext(TypeSystemClang *ts, clang::DeclContext *decl_ctx,
+ std::vector<lldb_private::CompilerContext> &context) {
+ if (decl_ctx == nullptr)
+ return;
+ InsertCompilerContext(ts, decl_ctx->getParent(), context);
+ clang::Decl::Kind clang_kind = decl_ctx->getDeclKind();
+ if (clang_kind == Decl::TranslationUnit)
+ return; // Stop at the translation unit.
+ const CompilerContextKind compiler_kind =
+ GetCompilerKind(clang_kind, decl_ctx);
+ ConstString decl_ctx_name = ts->DeclContextGetName(decl_ctx);
+ context.push_back({compiler_kind, decl_ctx_name});
+}
+
+std::vector<lldb_private::CompilerContext>
+TypeSystemClang::DeclGetCompilerContext(void *opaque_decl) {
+ std::vector<lldb_private::CompilerContext> context;
+ ConstString decl_name = DeclGetName(opaque_decl);
+ if (decl_name) {
+ clang::Decl *decl = (clang::Decl *)opaque_decl;
+ // Add the entire decl context first
+ clang::DeclContext *decl_ctx = decl->getDeclContext();
+ InsertCompilerContext(this, decl_ctx, context);
+ // Now add the decl information
+ auto compiler_kind =
+ GetCompilerKind(decl->getKind(), dyn_cast<DeclContext>(decl));
+ context.push_back({compiler_kind, decl_name});
+ }
+ return context;
+}
+
CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
size_t idx) {
if (clang::FunctionDecl *func_decl =
@@ -9706,6 +9289,14 @@ bool TypeSystemClang::DeclContextIsClassMethod(void *opaque_decl_ctx) {
return false;
}
+std::vector<lldb_private::CompilerContext>
+TypeSystemClang::DeclContextGetCompilerContext(void *opaque_decl_ctx) {
+ auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
+ std::vector<lldb_private::CompilerContext> context;
+ InsertCompilerContext(this, decl_ctx, context);
+ return context;
+}
+
bool TypeSystemClang::DeclContextIsContainedInLookup(
void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
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 3105e5b2e80f..878ab8f01e61 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -183,8 +183,6 @@ public:
static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx);
- static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl);
-
static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl);
void SetMetadataAsUserID(const clang::Decl *decl, lldb::user_id_t user_id);
@@ -219,6 +217,9 @@ public:
static clang::DeclContext *GetDeclContextForType(const CompilerType &type);
+ CompilerDeclContext
+ GetCompilerDeclContextForType(const CompilerType &type) override;
+
uint32_t GetPointerByteSize() override;
clang::TranslationUnitDecl *GetTranslationUnitDecl() {
@@ -514,7 +515,7 @@ public:
size_t bit_size);
// TypeSystem methods
- DWARFASTParser *GetDWARFParser() override;
+ plugin::dwarf::DWARFASTParser *GetDWARFParser() override;
#ifdef LLDB_ENABLE_ALL
PDBASTParser *GetPDBParser() override;
npdb::PdbAstBuilder *GetNativePDBParser() override;
@@ -557,6 +558,9 @@ public:
CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
size_t arg_idx) override;
+ std::vector<lldb_private::CompilerContext>
+ DeclGetCompilerContext(void *opaque_decl) override;
+
CompilerType GetTypeForDecl(void *opaque_decl) override;
// CompilerDeclContext override functions
@@ -586,6 +590,9 @@ public:
lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) override;
+ std::vector<lldb_private::CompilerContext>
+ DeclContextGetCompilerContext(void *opaque_decl_ctx) override;
+
// Clang specific clang::DeclContext functions
static clang::DeclContext *
@@ -634,8 +641,7 @@ public:
bool IsConst(lldb::opaque_compiler_type_t type) override;
- bool IsCStringType(lldb::opaque_compiler_type_t type,
- uint32_t &length) override;
+ bool IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length);
static bool IsCXXClassType(const CompilerType &type);
@@ -802,6 +808,10 @@ public:
// Create related types using the current type's AST
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override;
+ // Create a generic function prototype that can be used in ValuObject types
+ // to correctly display a function pointer with the right value and summary.
+ CompilerType CreateGenericFunctionPrototype() override;
+
// Exploring the type
const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override;
@@ -981,8 +991,8 @@ public:
const char *name, // the full symbol name as seen in the symbol table
// (lldb::opaque_compiler_type_t type, "-[NString
// stringWithCString:]")
- const CompilerType &method_compiler_type, lldb::AccessType access,
- bool is_artificial, bool is_variadic, bool is_objc_direct_call);
+ const CompilerType &method_compiler_type, bool is_artificial,
+ bool is_variadic, bool is_objc_direct_call);
static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type,
bool has_extern);
@@ -1031,23 +1041,12 @@ public:
/// The name of the symbol to dump, if it is empty dump all the symbols
void DumpFromSymbolFile(Stream &s, llvm::StringRef symbol_name);
- void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
- Stream &s, lldb::Format format, const DataExtractor &data,
- lldb::offset_t data_offset, size_t data_byte_size,
- uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
- bool show_types, bool show_summary, bool verbose,
- uint32_t depth) override;
-
bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream &s,
lldb::Format format, const DataExtractor &data,
lldb::offset_t data_offset, size_t data_byte_size,
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
ExecutionContextScope *exe_scope) override;
- void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
- Stream &s, const DataExtractor &data,
- lldb::offset_t data_offset, size_t data_byte_size) override;
-
void DumpTypeDescription(
lldb::opaque_compiler_type_t type,
lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override;