summaryrefslogtreecommitdiff
path: root/source/Plugins
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
commitead246455adf1a215ec2715dad6533073a6beb4e (patch)
treef3f97a47d77053bf96fe74cdbd6fae74380e8a92 /source/Plugins
parentfdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff)
Notes
Diffstat (limited to 'source/Plugins')
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp4
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h4
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp12
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h4
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp4
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h4
-rw-r--r--source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp614
-rw-r--r--source/Plugins/ABI/SysV-arc/ABISysV_arc.h106
-rw-r--r--source/Plugins/ABI/SysV-arc/CMakeLists.txt11
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp4
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.h4
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp13
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h4
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp4
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h4
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp4
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.h4
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp29
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.h4
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp29
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h4
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp28
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h4
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp46
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h4
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp21
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h4
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp59
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h4
-rw-r--r--source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp27
-rw-r--r--source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h4
-rw-r--r--source/Plugins/Architecture/Mips/ArchitectureMips.cpp8
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp13
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp50
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp37
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp232
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h23
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp203
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp46
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTDumper.cpp8
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp30
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp456
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp30
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h50
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h3
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp341
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h2
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp285
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h11
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp42
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h31
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp3
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangHost.cpp21
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp22
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h9
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp23
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h19
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp189
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.h37
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp2
-rw-r--r--source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp82
-rw-r--r--source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h84
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp22
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.cpp663
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.h36
-rw-r--r--source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h10
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp1
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp4
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp1
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp1
-rw-r--r--source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp1
-rw-r--r--source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp2
-rw-r--r--source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp12
-rw-r--r--source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp2
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp124
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td9
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp14
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp59
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp51
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.h6
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp15
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp1
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp11
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp39
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp1
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp13
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp29
-rw-r--r--source/Plugins/Language/ObjC/CoreMedia.cpp20
-rw-r--r--source/Plugins/Language/ObjC/NSArray.cpp26
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.h4
-rw-r--r--source/Plugins/Language/ObjC/NSString.cpp22
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.cpp1
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp2
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp111
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp133
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h8
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp23
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp12
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp162
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp62
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp49
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h32
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp25
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp36
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h1
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp8
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp733
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h12
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp11
-rw-r--r--source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp98
-rw-r--r--source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h25
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp4
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h9
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp425
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h27
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp2
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.h7
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp56
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp71
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp108
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h2
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp42
-rw-r--r--source/Plugins/Process/Darwin/MachException.cpp194
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.cpp568
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp18
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp28
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp60
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp140
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h4
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp11
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h4
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp4
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.cpp7
-rw-r--r--source/Plugins/Process/POSIX/NativeProcessELF.cpp72
-rw-r--r--source/Plugins/Process/POSIX/NativeProcessELF.h7
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.cpp7
-rw-r--r--source/Plugins/Process/Utility/AuxVector.cpp6
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp114
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.cpp8
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.cpp4
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h3
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp87
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.h3
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp15
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp20
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp16
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp227
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.h6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp89
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_i386.h27
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp152
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h28
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm64.h439
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp900
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp96
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.h3
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp6
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h3
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp51
-rw-r--r--source/Plugins/Process/elf-core/RegisterUtilities.h40
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp70
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h66
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp206
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp184
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h8
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp75
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h85
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp18
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp12
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp106
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp664
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp56
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp55
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp781
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h10
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td16
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp8
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.cpp53
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h2
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.cpp37
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.h113
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.cpp94
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h2
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp38
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h6
-rw-r--r--source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp4
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp1244
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h622
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp169
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h56
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp567
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h3
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h53
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp330
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td12
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp257
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h84
-rw-r--r--source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp37
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParser.h5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp1078
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h91
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp32
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp20
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp1038
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h227
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp67
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h50
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp959
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h72
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp237
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h50
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp12
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h3
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td12
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp2
-rw-r--r--source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp29
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h7
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp60
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp143
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h58
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp23
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp2
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp345
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h56
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp38
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h18
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp144
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp32
252 files changed, 11181 insertions, 10492 deletions
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 362a80be4b0d..9dff12bcc748 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -1326,7 +1326,8 @@ ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
if (vendor_type == llvm::Triple::Apple) {
if ((arch_type == llvm::Triple::arm) ||
(arch_type == llvm::Triple::thumb)) {
- return ABISP(new ABIMacOSX_arm(process_sp));
+ return ABISP(
+ new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1846,6 +1847,7 @@ bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
index ac9ba00b9d91..e512651f86e5 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
@@ -85,7 +85,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABIMacOSX_arm(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index 368e37213249..6473ccf9a19a 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -1665,8 +1665,10 @@ ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type == llvm::Triple::Apple) {
- if (arch_type == llvm::Triple::aarch64) {
- return ABISP(new ABIMacOSX_arm64(process_sp));
+ if (arch_type == llvm::Triple::aarch64 ||
+ arch_type == llvm::Triple::aarch64_32) {
+ return ABISP(
+ new ABIMacOSX_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1710,9 +1712,8 @@ bool ABIMacOSX_arm64::PrepareTrivialCall(
for (size_t i = 0; i < args.size(); ++i) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s",
+ static_cast<int>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
@@ -2011,6 +2012,7 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
index bfacbcd54a94..c7a91ba9c468 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
@@ -93,7 +93,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABIMacOSX_arm64(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 67371b432ff8..76ebd6476ffd 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -710,7 +710,8 @@ ABIMacOSX_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch)
if ((arch.GetTriple().getArch() == llvm::Triple::x86) &&
(arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS() ||
arch.GetTriple().isWatchOS())) {
- return ABISP(new ABIMacOSX_i386(process_sp));
+ return ABISP(
+ new ABIMacOSX_i386(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -1055,6 +1056,7 @@ bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("i386 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
index 57def683283f..50062b84d878 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
@@ -92,7 +92,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABIMacOSX_i386(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABIMacOSX_i386(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp b/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp
new file mode 100644
index 000000000000..715b5e5d2b95
--- /dev/null
+++ b/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp
@@ -0,0 +1,614 @@
+//===-- ABISysV_arc.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 "ABISysV_arc.h"
+
+// C Includes
+// C++ Includes
+#include <array>
+#include <limits>
+#include <type_traits>
+
+// Other libraries and framework includes
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/Support/MathExtras.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.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, 0 \
+ }
+
+#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;
+
+namespace {
+namespace dwarf {
+enum regnums {
+ r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16,
+ r17, r18, r19, r20, r21, r22, r23, r24, r25, r26,
+ r27, fp = r27, r28, sp = r28, r29, r30, r31, blink = r31,
+ r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46,
+ r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60,
+ /*reserved,*/ /*limm indicator,*/ r63 = 63, pc = 70, status32 = 74
+};
+
+static const std::array<RegisterInfo, 64> g_register_infos = { {
+ DEFINE_GENERIC_REGISTER_STUB(r0, nullptr, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GENERIC_REGISTER_STUB(r1, nullptr, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GENERIC_REGISTER_STUB(r2, nullptr, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GENERIC_REGISTER_STUB(r3, nullptr, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GENERIC_REGISTER_STUB(r4, nullptr, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GENERIC_REGISTER_STUB(r5, nullptr, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GENERIC_REGISTER_STUB(r6, nullptr, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GENERIC_REGISTER_STUB(r7, nullptr, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_REGISTER_STUB(r8, nullptr),
+ DEFINE_REGISTER_STUB(r9, nullptr),
+ DEFINE_REGISTER_STUB(r10, nullptr),
+ DEFINE_REGISTER_STUB(r11, nullptr),
+ DEFINE_REGISTER_STUB(r12, nullptr),
+ DEFINE_REGISTER_STUB(r13, nullptr),
+ DEFINE_REGISTER_STUB(r14, nullptr),
+ DEFINE_REGISTER_STUB(r15, nullptr),
+ DEFINE_REGISTER_STUB(r16, nullptr),
+ DEFINE_REGISTER_STUB(r17, nullptr),
+ DEFINE_REGISTER_STUB(r18, nullptr),
+ DEFINE_REGISTER_STUB(r19, nullptr),
+ DEFINE_REGISTER_STUB(r20, nullptr),
+ DEFINE_REGISTER_STUB(r21, nullptr),
+ DEFINE_REGISTER_STUB(r22, nullptr),
+ DEFINE_REGISTER_STUB(r23, nullptr),
+ DEFINE_REGISTER_STUB(r24, nullptr),
+ DEFINE_REGISTER_STUB(r25, nullptr),
+ DEFINE_REGISTER_STUB(r26, "gp"),
+ DEFINE_GENERIC_REGISTER_STUB(r27, "fp", LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GENERIC_REGISTER_STUB(r28, "sp", LLDB_REGNUM_GENERIC_SP),
+ DEFINE_REGISTER_STUB(r29, "ilink"),
+ DEFINE_REGISTER_STUB(r30, nullptr),
+ DEFINE_GENERIC_REGISTER_STUB(r31, "blink", LLDB_REGNUM_GENERIC_RA),
+ DEFINE_REGISTER_STUB(r32, nullptr),
+ DEFINE_REGISTER_STUB(r33, nullptr),
+ DEFINE_REGISTER_STUB(r34, nullptr),
+ DEFINE_REGISTER_STUB(r35, nullptr),
+ DEFINE_REGISTER_STUB(r36, nullptr),
+ DEFINE_REGISTER_STUB(r37, nullptr),
+ DEFINE_REGISTER_STUB(r38, nullptr),
+ DEFINE_REGISTER_STUB(r39, nullptr),
+ DEFINE_REGISTER_STUB(r40, nullptr),
+ DEFINE_REGISTER_STUB(r41, nullptr),
+ DEFINE_REGISTER_STUB(r42, nullptr),
+ DEFINE_REGISTER_STUB(r43, nullptr),
+ DEFINE_REGISTER_STUB(r44, nullptr),
+ DEFINE_REGISTER_STUB(r45, nullptr),
+ DEFINE_REGISTER_STUB(r46, nullptr),
+ DEFINE_REGISTER_STUB(r47, nullptr),
+ DEFINE_REGISTER_STUB(r48, nullptr),
+ DEFINE_REGISTER_STUB(r49, nullptr),
+ DEFINE_REGISTER_STUB(r50, nullptr),
+ DEFINE_REGISTER_STUB(r51, nullptr),
+ DEFINE_REGISTER_STUB(r52, nullptr),
+ DEFINE_REGISTER_STUB(r53, nullptr),
+ DEFINE_REGISTER_STUB(r54, nullptr),
+ DEFINE_REGISTER_STUB(r55, nullptr),
+ DEFINE_REGISTER_STUB(r56, nullptr),
+ DEFINE_REGISTER_STUB(r57, nullptr),
+ DEFINE_REGISTER_STUB(r58, "accl"),
+ DEFINE_REGISTER_STUB(r59, "acch"),
+ DEFINE_REGISTER_STUB(r60, "lp_count"),
+ DEFINE_REGISTER_STUB(r63, "pcl"),
+ DEFINE_GENERIC_REGISTER_STUB(pc, nullptr, LLDB_REGNUM_GENERIC_PC),
+ DEFINE_GENERIC_REGISTER_STUB(status32, nullptr, LLDB_REGNUM_GENERIC_FLAGS)} };
+} // namespace dwarf
+} // namespace
+
+const RegisterInfo *ABISysV_arc::GetRegisterInfoArray(uint32_t &count) {
+ count = dwarf::g_register_infos.size();
+ return dwarf::g_register_infos.data();
+}
+
+size_t ABISysV_arc::GetRedZoneSize() const { return 0; }
+
+bool ABISysV_arc::IsRegisterFileReduced(RegisterContext &reg_ctx) const {
+ if (!m_is_reg_file_reduced) {
+ const auto *const rf_build_reg = reg_ctx.GetRegisterInfoByName("rf_build");
+
+ const auto reg_value = reg_ctx.ReadRegisterAsUnsigned(rf_build_reg,
+ /*fail_value*/ 0);
+ // RF_BUILD "Number of Entries" bit.
+ const uint32_t rf_entries_bit = 1U << 9U;
+ m_is_reg_file_reduced = (reg_value | rf_entries_bit) != 0;
+ }
+
+ return m_is_reg_file_reduced.getValueOr(false);
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+
+ABISP ABISysV_arc::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
+ return llvm::Triple::arc == arch.GetTriple().getArch() ?
+ ABISP(new ABISysV_arc(std::move(process_sp), MakeMCRegisterInfo(arch))) :
+ ABISP();
+}
+
+namespace {
+const size_t word_size = 4U;
+const size_t reg_size = word_size;
+
+inline size_t AugmentArgSize(size_t size_in_bytes) {
+ return llvm::alignTo(size_in_bytes, word_size);
+}
+
+size_t TotalArgsSizeInWords(const llvm::ArrayRef<ABI::CallArgument> &args) {
+ size_t total_size = 0;
+ for (const auto &arg : args)
+ total_size +=
+ (ABI::CallArgument::TargetValue == arg.type ? AugmentArgSize(arg.size)
+ : reg_size) /
+ word_size;
+
+ return total_size;
+}
+} // namespace
+
+bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ // We don't use the traditional trivial call specialized for jit.
+ return false;
+}
+
+bool ABISysV_arc::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;
+
+ // 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 stack for this data 4-byte aligned.
+ sp -= AugmentArgSize(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.isFunctionVarArg());
+ assert(prototype.getFunctionNumParams() == args.size());
+
+ const size_t regs_for_args_count = IsRegisterFileReduced(*reg_ctx) ? 4U : 8U;
+
+ // Number of arguments passed on stack.
+ auto args_size = TotalArgsSizeInWords(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[reg_size];
+ size_t reg_index = LLDB_REGNUM_GENERIC_ARG1;
+
+ for (const auto &arg : args) {
+ auto value = reinterpret_cast<const uint8_t *>(&arg.value);
+ auto size =
+ ABI::CallArgument::TargetValue == arg.type ? arg.size : reg_size;
+
+ // Pass arguments via registers.
+ while (size > 0 && reg_index < regs_for_args_count) {
+ size_t byte_index = 0;
+ auto end = size < reg_size ? size : reg_size;
+
+ while (byte_index < end) {
+ reg_value[byte_index++] = *(value++);
+ --size;
+ }
+
+ while (byte_index < reg_size) {
+ reg_value[byte_index++] = 0;
+ }
+
+ RegisterValue reg_val_obj(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.
+ ++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(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_arc::GetArgumentValues(Thread &thread, ValueList &values) const {
+ return false;
+}
+
+Status ABISysV_arc::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;
+ }
+
+ 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.
+
+ raw_value >>= 32;
+ 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;
+}
+
+namespace {
+template <typename T>
+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);
+}
+
+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;
+}
+
+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;
+}
+
+uint64_t ReadRawValue(const RegisterContextSP &reg_ctx, uint8_t size_in_bytes) {
+ auto reg_info_r0 =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+
+ // Extract the register context so we can read arguments from registers.
+ uint64_t raw_value =
+ reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0) & UINT32_MAX;
+
+ if (sizeof(uint64_t) == size_in_bytes)
+ raw_value |= (reg_ctx->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG2), 0) &
+ UINT64_MAX) << 32U;
+
+ return raw_value;
+}
+} // namespace
+
+ValueObjectSP
+ABISysV_arc::GetReturnValueObjectSimple(Thread &thread,
+ CompilerType &compiler_type) const {
+ if (!compiler_type)
+ return ValueObjectSP();
+
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return ValueObjectSP();
+
+ Value value;
+ value.SetCompilerType(compiler_type);
+
+ const uint32_t type_flags = compiler_type.GetTypeInfo();
+ // Integer return type.
+ if (type_flags & eTypeIsInteger) {
+ const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
+ return ValueObjectSP();
+
+ value.SetValueType(Value::eValueTypeScalar);
+ }
+ // Pointer return type.
+ else if (type_flags & eTypeIsPointer) {
+ auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
+
+ value.SetValueType(Value::eValueTypeScalar);
+ }
+ // 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) &&
+ 1 == float_count && !is_complex) {
+ const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
+ return ValueObjectSP();
+ }
+ }
+ // Unsupported return type.
+ else
+ return ValueObjectSP();
+
+ return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+}
+
+ValueObjectSP ABISysV_arc::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);
+}
+
+ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread,
+ llvm::Type &retType) const {
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return ValueObjectSP();
+
+ Value value;
+ // Void return type.
+ if (retType.isVoidTy()) {
+ value.GetScalar() = 0;
+ }
+ // Integer return type.
+ else if (retType.isIntegerTy()) {
+ size_t byte_size = retType.getPrimitiveSizeInBits();
+ if (1 != byte_size) // For boolian type.
+ byte_size /= CHAR_BIT;
+
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ const bool is_signed = false; // IR Type doesn't provide this info.
+ if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
+ return ValueObjectSP();
+ }
+ // Pointer return type.
+ else if (retType.isPointerTy()) {
+ auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ }
+ // Floating point return type.
+ else if (retType.isFloatingPointTy()) {
+ const size_t byte_size = retType.getPrimitiveSizeInBits() / CHAR_BIT;
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
+ return ValueObjectSP();
+ }
+ // Unsupported return type.
+ else
+ return ValueObjectSP();
+
+ return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+}
+
+bool ABISysV_arc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our Call Frame Address is the stack pointer value.
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf::sp, 0);
+
+ // The previous PC is in the BLINK.
+ row->SetRegisterLocationToRegister(dwarf::pc, dwarf::blink, true);
+ unwind_plan.AppendRow(row);
+
+ // All other registers are the same.
+ unwind_plan.SetSourceName("arc at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
+}
+
+bool ABISysV_arc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ return false;
+}
+
+bool ABISysV_arc::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (nullptr == reg_info)
+ return false;
+
+ // Volatile registers are: r0..r12.
+ uint32_t regnum = reg_info->kinds[eRegisterKindDWARF];
+ if (regnum <= 12)
+ return true;
+
+ static const std::string ra_reg_name = "blink";
+ return ra_reg_name == reg_info->name;
+}
+
+void ABISysV_arc::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "System V ABI for ARC targets", CreateInstance);
+}
+
+void ABISysV_arc::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString ABISysV_arc::GetPluginNameStatic() {
+ static ConstString g_name("sysv-arc");
+ return g_name;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+ConstString ABISysV_arc::GetPluginName() {
+ return GetPluginNameStatic();
+}
+
+uint32_t ABISysV_arc::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-arc/ABISysV_arc.h b/source/Plugins/ABI/SysV-arc/ABISysV_arc.h
new file mode 100644
index 000000000000..c4b26a54158c
--- /dev/null
+++ b/source/Plugins/ABI/SysV-arc/ABISysV_arc.h
@@ -0,0 +1,106 @@
+//===-- ArchitectureArc.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_arc_h_
+#define liblldb_ABISysV_arc_h_
+
+// Other libraries and framework includes
+#include <llvm/ADT/Optional.h>
+
+// Project includes
+#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
+
+class ABISysV_arc : public lldb_private::ABI {
+public:
+ ~ABISysV_arc() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ 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 {
+ // Stack call frame address must be 4 byte aligned.
+ return (cfa & 0x3ull) == 0;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Code addresse must be 2 byte aligned.
+ return (pc & 1ull) == 0;
+ }
+
+ 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 lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+private:
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
+
+ bool IsRegisterFileReduced(lldb_private::RegisterContext &reg_ctx) const;
+
+ using lldb_private::ABI::ABI; // Call CreateInstance instead.
+
+ using RegisterFileFlag = llvm::Optional<bool>;
+ mutable RegisterFileFlag m_is_reg_file_reduced;
+};
+
+#endif // liblldb_ABISysV_arc_h_
diff --git a/source/Plugins/ABI/SysV-arc/CMakeLists.txt b/source/Plugins/ABI/SysV-arc/CMakeLists.txt
new file mode 100644
index 000000000000..3dc0d1c65b46
--- /dev/null
+++ b/source/Plugins/ABI/SysV-arc/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginABISysV_arc PLUGIN
+ ABISysV_arc.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ lldbPluginProcessUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index dd47ac7cbe3c..b6e8f8806829 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -1327,7 +1327,8 @@ ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (vendor_type != llvm::Triple::Apple) {
if ((arch_type == llvm::Triple::arm) ||
(arch_type == llvm::Triple::thumb)) {
- return ABISP(new ABISysV_arm(process_sp));
+ return ABISP(
+ new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1960,6 +1961,7 @@ bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
index a0f00c8f227d..60fb14be5f7b 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
@@ -85,7 +85,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_arm(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index 1d547121e231..89a1f2b3cf04 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -1668,8 +1668,10 @@ ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch)
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type != llvm::Triple::Apple) {
- if (arch_type == llvm::Triple::aarch64) {
- return ABISP(new ABISysV_arm64(process_sp));
+ if (arch_type == llvm::Triple::aarch64 ||
+ arch_type == llvm::Triple::aarch64_32) {
+ return ABISP(
+ new ABISysV_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1706,9 +1708,8 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s",
+ static_cast<int>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
@@ -1958,6 +1959,7 @@ bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm64 at-func-entry default");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
@@ -1982,6 +1984,7 @@ bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
index 1fbdc793ed6e..1bf5773e2db3 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
@@ -92,7 +92,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_arm64(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
index 93647564fe25..34d9258ccb92 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
@@ -1014,7 +1014,8 @@ size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
- return ABISP(new ABISysV_hexagon(process_sp));
+ return ABISP(
+ new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -1247,6 +1248,7 @@ bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("hexagon default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
index 459b6315dba2..bef64a22d95f 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
@@ -97,7 +97,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_hexagon(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_hexagon(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index 05f5dba90687..69e4cff90ebf 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -198,7 +198,8 @@ ABISP
ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getVendor() != llvm::Triple::Apple) {
if (arch.GetTriple().getArch() == llvm::Triple::x86) {
- return ABISP(new ABISysV_i386(process_sp));
+ return ABISP(
+ new ABISysV_i386(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
return ABISP();
@@ -785,6 +786,7 @@ bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("i386 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
index 982bdd676b74..2362e9adda98 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
@@ -100,7 +100,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_i386(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_i386(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index 121c7300b968..416db9f5ae87 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -556,7 +556,8 @@ ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
if ((arch_type == llvm::Triple::mips) ||
(arch_type == llvm::Triple::mipsel)) {
- return ABISP(new ABISysV_mips(process_sp));
+ return ABISP(
+ new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -600,9 +601,8 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
- args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
+ args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
@@ -630,9 +630,8 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
size_t i = 4;
for (; ai != ae; ++ai) {
reg_value.SetUInt32(*ai);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "",
- i + 1, args[i], arg_pos);
+ LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "",
+ i + 1, args[i], arg_pos);
if (reg_ctx
->WriteRegisterValueToMemory(reg_info, arg_pos,
@@ -654,8 +653,7 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
- if (log)
- log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+ LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
/* Write r0 with 0, in case we are stopped in syscall,
* such setting prevents automatic decrement of the PC.
@@ -664,29 +662,25 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
return false;
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
// Set "sp" to the requested value
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
// Set "ra" to the return address
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
return false;
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
// Set pc to the address of the called function.
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
- if (log)
- log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
// All callers of position independent functions must place the address of
// the called function in t9 (r25)
@@ -997,6 +991,7 @@ bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("mips default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
index 6cd9c19c22ac..8143f552fc4d 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
@@ -87,7 +87,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_mips(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index 18011cfb6b9e..72ec0715b6cd 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -554,7 +554,8 @@ size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().isMIPS64())
- return ABISP(new ABISysV_mips64(process_sp));
+ return ABISP(
+ new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch)));
return ABISP();
}
@@ -589,18 +590,16 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
- args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
+ args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -614,8 +613,7 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
- if (log)
- log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+ LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
/* Write r0 with 0, in case we are stopped in syscall,
* such setting prevents automatic decrement of the PC.
@@ -624,29 +622,25 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
return false;
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
// Set "sp" to the requested value
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
// Set "ra" to the return address
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
return false;
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
// Set pc to the address of the called function.
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
- if (log)
- log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
// All callers of position independent functions must place the address of
// the called function in t9 (r25)
@@ -1168,6 +1162,7 @@ bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("mips64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
index 7da71b36b4b7..76c3c5413b92 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
@@ -100,7 +100,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_mips64(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index faa995033ac2..857b7fee10e3 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -218,7 +218,8 @@ size_t ABISysV_ppc::GetRedZoneSize() const { return 224; }
ABISP
ABISysV_ppc::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::ppc) {
- return ABISP(new ABISysV_ppc(process_sp));
+ return ABISP(
+ new ABISysV_ppc(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -255,18 +256,16 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -281,10 +280,10 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
RegisterValue reg_value;
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- ": 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
@@ -292,16 +291,14 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
// %r1 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
@@ -910,6 +907,7 @@ bool ABISysV_ppc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("ppc default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_lr);
return true;
}
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
index 3b199852c30d..59907c4648ba 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
@@ -96,7 +96,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_ppc(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index aa7907550f29..935353c38ca4 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -70,7 +70,8 @@ ABISP
ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp,
const ArchSpec &arch) {
if (arch.GetTriple().isPPC64())
- return ABISP(new ABISysV_ppc64(process_sp));
+ return ABISP(
+ new ABISysV_ppc64(std::move(process_sp), MakeMCRegisterInfo(arch)));
return ABISP();
}
@@ -106,18 +107,16 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -136,22 +135,20 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
const RegisterInfo *r12_reg_info = reg_ctx->GetRegisterInfoAtIndex(12);
// Save return address onto the stack.
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- "(+16): 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ "(+16): 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
if (!process_sp->WritePointerToMemory(sp + 16, return_addr, error))
return false;
// Write the return address to link register.
- if (log)
- log->Printf("Writing LR: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing LR: 0x%" PRIx64, (uint64_t)return_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(lr_reg_info, return_addr))
return false;
// Write target address to %r12 register.
- if (log)
- log->Printf("Writing R12: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing R12: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(r12_reg_info, func_addr))
return false;
@@ -165,10 +162,9 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
else
stack_offset = 40;
- if (log)
- log->Printf("Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64,
- (uint64_t)(sp + stack_offset), (int)stack_offset,
- (uint64_t)reg_value);
+ LLDB_LOGF(log, "Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64,
+ (uint64_t)(sp + stack_offset), (int)stack_offset,
+ (uint64_t)reg_value);
if (!process_sp->WritePointerToMemory(sp + stack_offset, reg_value, error))
return false;
@@ -176,23 +172,20 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
reg_value = reg_ctx->ReadRegisterAsUnsigned(sp_reg_info, 0);
// Save current SP onto the stack.
- if (log)
- log->Printf("Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp,
- (uint64_t)reg_value);
+ LLDB_LOGF(log, "Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp,
+ (uint64_t)reg_value);
if (!process_sp->WritePointerToMemory(sp, reg_value, error))
return false;
// %r1 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
@@ -1017,6 +1010,7 @@ bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("ppc64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(pc_reg_num);
return true;
}
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
index d5fb09eec0d0..1b58975dd9d9 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
@@ -96,7 +96,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_ppc64(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
index abe847b386a8..f4f803a8277d 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
@@ -200,7 +200,7 @@ size_t ABISysV_s390x::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::systemz) {
- return ABISP(new ABISysV_s390x(process_sp));
+ return ABISP(new ABISysV_s390x(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -252,16 +252,14 @@ bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
if (i < 5) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
} else {
Status error;
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
- static_cast<uint64_t>(i + 1), args[i]);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
+ static_cast<uint64_t>(i + 1), args[i]);
if (!process_sp->WritePointerToMemory(arg_pos, args[i], error))
return false;
arg_pos += 8;
@@ -270,24 +268,21 @@ bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
// %r14 is set to the return address
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
return false;
// %r15 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
index 13df477e84bc..671d6a18260e 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
@@ -88,7 +88,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_s390x(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_s390x(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 6c7b45f63399..bf1c48f778e1 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -222,17 +222,35 @@ ABISP
ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
const llvm::Triple::OSType os_type = arch.GetTriple().getOS();
+ const llvm::Triple::EnvironmentType os_env =
+ arch.GetTriple().getEnvironment();
if (arch_type == llvm::Triple::x86_64) {
switch(os_type) {
- case llvm::Triple::OSType::MacOSX:
- case llvm::Triple::OSType::Linux:
- case llvm::Triple::OSType::FreeBSD:
- case llvm::Triple::OSType::NetBSD:
- case llvm::Triple::OSType::Solaris:
- case llvm::Triple::OSType::UnknownOS:
- return ABISP(new ABISysV_x86_64(process_sp));
- default:
+ case llvm::Triple::OSType::IOS:
+ case llvm::Triple::OSType::TvOS:
+ case llvm::Triple::OSType::WatchOS:
+ switch (os_env) {
+ case llvm::Triple::EnvironmentType::MacABI:
+ case llvm::Triple::EnvironmentType::Simulator:
+ case llvm::Triple::EnvironmentType::UnknownEnvironment:
+ // UnknownEnvironment is needed for older compilers that don't
+ // support the simulator environment.
+ return ABISP(new ABISysV_x86_64(std::move(process_sp),
+ MakeMCRegisterInfo(arch)));
+ default:
return ABISP();
+ }
+ case llvm::Triple::OSType::Darwin:
+ case llvm::Triple::OSType::FreeBSD:
+ case llvm::Triple::OSType::Linux:
+ case llvm::Triple::OSType::MacOSX:
+ case llvm::Triple::OSType::NetBSD:
+ case llvm::Triple::OSType::Solaris:
+ case llvm::Triple::OSType::UnknownOS:
+ return ABISP(
+ new ABISysV_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
+ default:
+ return ABISP();
}
}
return ABISP();
@@ -270,18 +288,16 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -295,10 +311,10 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
ProcessSP process_sp(thread.GetProcess());
RegisterValue reg_value;
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- ": 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
@@ -306,16 +322,14 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
// %rsp is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %rip is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
@@ -1034,6 +1048,7 @@ bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("x86_64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
index f6704aff348c..d445d8f4142a 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
@@ -98,7 +98,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_x86_64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABISysV_x86_64(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
index 5dc7717d865d..ac24426914e1 100644
--- a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
+++ b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
@@ -1092,7 +1092,8 @@ ABISP
ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::x86_64 &&
arch.GetTriple().isOSWindows()) {
- return ABISP(new ABIWindows_x86_64(process_sp));
+ return ABISP(
+ new ABIWindows_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -1129,18 +1130,16 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -1154,10 +1153,10 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
ProcessSP process_sp(thread.GetProcess());
RegisterValue reg_value;
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- ": 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
@@ -1165,16 +1164,14 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
// %rsp is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %rip is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
diff --git a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
index 9f6b2ceef299..2366566d7809 100644
--- a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
+++ b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
@@ -91,7 +91,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABIWindows_x86_64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ ABIWindows_x86_64(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
// Call CreateInstance instead.
}
};
diff --git a/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
index 60f1a2eb7572..5f2f6eeb8261 100644
--- a/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
+++ b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
@@ -127,10 +127,10 @@ lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr,
// Adjust the breakable address
uint64_t breakable_addr = addr - insn->GetOpcode().GetByteSize();
- if (log)
- log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64
- " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n",
- __FUNCTION__, addr, breakable_addr);
+ LLDB_LOGF(log,
+ "Target::%s Breakpoint at 0x%8.8" PRIx64
+ " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n",
+ __FUNCTION__, addr, breakable_addr);
return breakable_addr;
}
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 44c75fc953c8..28c9de2c1e96 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -381,11 +381,10 @@ public:
static RegularExpression s_regex(
llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?"));
- RegularExpression::Match matches(3);
-
+ llvm::SmallVector<llvm::StringRef, 4> matches;
if (s_regex.Execute(out_string, &matches)) {
- matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
- matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
+ m_opcode_name = matches[1].str();
+ m_mnemonics = matches[2].str();
}
}
}
@@ -1190,10 +1189,12 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
// If any AArch64 variant, enable the ARMv8.5 ISA with SVE extensions so we
// can disassemble newer instructions.
- if (triple.getArch() == llvm::Triple::aarch64)
+ if (triple.getArch() == llvm::Triple::aarch64 ||
+ triple.getArch() == llvm::Triple::aarch64_32)
features_str += "+v8.5a,+sve2";
- if (triple.getArch() == llvm::Triple::aarch64
+ if ((triple.getArch() == llvm::Triple::aarch64 ||
+ triple.getArch() == llvm::Triple::aarch64_32)
&& triple.getVendor() == llvm::Triple::Apple) {
cpu = "apple-latest";
}
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 23c8416f4986..5b19647a27ba 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -277,8 +277,7 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
// Do not try to set the breakpoint if we don't know where to put it
if (break_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Unable to locate _rtld_debug_state breakpoint address");
+ LLDB_LOGF(log, "Unable to locate _rtld_debug_state breakpoint address");
return false;
}
@@ -301,7 +300,7 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
.GetID() == m_dyld_bid);
if (log && dyld_break == nullptr)
- log->Printf("Failed to create _rtld_debug_state breakpoint");
+ LLDB_LOGF(log, "Failed to create _rtld_debug_state breakpoint");
// check we have successfully set bp
return (dyld_break != nullptr);
@@ -316,8 +315,7 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
user_id_t break_loc_id) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("Rendezvous breakpoint hit!");
+ LLDB_LOGF(log, "Rendezvous breakpoint hit!");
DynamicLoaderHexagonDYLD *dyld_instance = nullptr;
dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton);
@@ -333,11 +331,9 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
if (structAddr != LLDB_INVALID_ADDRESS) {
dyld_instance->m_rendezvous.SetRendezvousAddress(structAddr);
- if (log)
- log->Printf("Found _rtld_debug structure @ 0x%08" PRIx64, structAddr);
+ LLDB_LOGF(log, "Found _rtld_debug structure @ 0x%08" PRIx64, structAddr);
} else {
- if (log)
- log->Printf("Unable to resolve the _rtld_debug structure");
+ LLDB_LOGF(log, "Unable to resolve the _rtld_debug structure");
}
}
@@ -375,11 +371,11 @@ void DynamicLoaderHexagonDYLD::RefreshModules() {
}
if (log) {
- log->Printf("Target is loading '%s'", I->path.c_str());
+ LLDB_LOGF(log, "Target is loading '%s'", I->path.c_str());
if (!module_sp.get())
- log->Printf("LLDB failed to load '%s'", I->path.c_str());
+ LLDB_LOGF(log, "LLDB failed to load '%s'", I->path.c_str());
else
- log->Printf("LLDB successfully loaded '%s'", I->path.c_str());
+ LLDB_LOGF(log, "LLDB successfully loaded '%s'", I->path.c_str());
}
}
m_process->GetTarget().ModulesDidLoad(new_modules);
@@ -400,8 +396,7 @@ void DynamicLoaderHexagonDYLD::RefreshModules() {
UnloadSections(module_sp);
}
- if (log)
- log->Printf("Target is unloading '%s'", I->path.c_str());
+ LLDB_LOGF(log, "Target is unloading '%s'", I->path.c_str());
}
loaded_modules.Remove(old_modules);
m_process->GetTarget().ModulesDidUnload(old_modules, false);
@@ -472,10 +467,10 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
if (!m_rendezvous.Resolve()) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf(
- "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address",
+ __FUNCTION__);
return;
}
@@ -493,10 +488,10 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
module_list.Append(module_sp);
} else {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::%s failed loading module %s at "
- "0x%" PRIx64,
- __FUNCTION__, module_path, I->base_addr);
+ LLDB_LOGF(log,
+ "DynamicLoaderHexagonDYLD::%s failed loading module %s at "
+ "0x%" PRIx64,
+ __FUNCTION__, module_path, I->base_addr);
}
}
@@ -604,12 +599,11 @@ DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module,
Module *mod = module.get();
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
- ", modid=%i, tls_block=0x%" PRIx64,
- mod->GetObjectName().AsCString(""), link_map, tp, modid,
- tls_block);
+ LLDB_LOGF(log,
+ "DynamicLoaderHexagonDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%i, tls_block=0x%" PRIx64,
+ mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block);
if (tls_block == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index 844a06c2b37d..f4788816d4ea 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -290,8 +290,9 @@ bool HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field,
Target &target = m_process->GetTarget();
SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
- eSymbolTypeAny, list))
+ target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list);
+ if (list.IsEmpty())
return false;
Address address = list[0].symbol->GetAddress();
@@ -339,16 +340,16 @@ void HexagonDYLDRendezvous::DumpToLog(Log *log) const {
return;
log->PutCString("HexagonDYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent)
- ? "consistent"
- : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
- : "unknown");
+ LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress());
+ LLDB_LOGF(log, " Version: %" PRIu64, GetVersion());
+ LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress());
+ LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress());
+ LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase());
+ LLDB_LOGF(log, " State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add"
+ : (state == eDelete) ? "delete" : "unknown");
iterator I = begin();
iterator E = end();
@@ -357,11 +358,11 @@ void HexagonDYLDRendezvous::DumpToLog(Log *log) const {
log->PutCString("HexagonDYLDRendezvous SOEntries:");
for (int i = 1; I != E; ++I, ++i) {
- log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
+ LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->path.c_str());
+ LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr);
+ LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr);
+ LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr);
+ LLDB_LOGF(log, " Next : %" PRIx64, I->next);
+ LLDB_LOGF(log, " Prev : %" PRIx64, I->prev);
}
}
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 0d736738ebb5..737599303a60 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -33,16 +33,14 @@ static addr_t ResolveRendezvousAddress(Process *process) {
Status error;
if (!process) {
- if (log)
- log->Printf("%s null process provided", __FUNCTION__);
+ LLDB_LOGF(log, "%s null process provided", __FUNCTION__);
return LLDB_INVALID_ADDRESS;
}
// Try to get it from our process. This might be a remote process and might
// grab it via some remote-specific mechanism.
info_location = process->GetImageInfoAddress();
- if (log)
- log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
+ LLDB_LOGF(log, "%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
// If the process fails to return an address, fall back to seeing if the
// local object file can help us find it.
@@ -54,42 +52,38 @@ static addr_t ResolveRendezvousAddress(Process *process) {
if (addr.IsValid()) {
info_location = addr.GetLoadAddress(target);
- if (log)
- log->Printf(
- "%s resolved via direct object file approach to 0x%" PRIx64,
- __FUNCTION__, info_location);
+ LLDB_LOGF(log,
+ "%s resolved via direct object file approach to 0x%" PRIx64,
+ __FUNCTION__, info_location);
} else {
- if (log)
- log->Printf("%s FAILED - direct object file approach did not yield a "
- "valid address",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "%s FAILED - direct object file approach did not yield a "
+ "valid address",
+ __FUNCTION__);
}
}
}
if (info_location == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("%s FAILED - invalid info address", __FUNCTION__);
+ LLDB_LOGF(log, "%s FAILED - invalid info address", __FUNCTION__);
return LLDB_INVALID_ADDRESS;
}
- if (log)
- log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
- __FUNCTION__, process->GetAddressByteSize(), info_location);
+ LLDB_LOGF(log, "%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
+ __FUNCTION__, process->GetAddressByteSize(), info_location);
info_addr = process->ReadPointerFromMemory(info_location, error);
if (error.Fail()) {
- if (log)
- log->Printf("%s FAILED - could not read from the info location: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "%s FAILED - could not read from the info location: %s",
+ __FUNCTION__, error.AsCString());
return LLDB_INVALID_ADDRESS;
}
if (info_addr == 0) {
- if (log)
- log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64
- " returned a null value",
- __FUNCTION__, info_location);
+ LLDB_LOGF(log,
+ "%s FAILED - the rendezvous address contained at 0x%" PRIx64
+ " returned a null value",
+ __FUNCTION__, info_location);
return LLDB_INVALID_ADDRESS;
}
@@ -109,14 +103,13 @@ DYLDRendezvous::DYLDRendezvous(Process *process)
Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
if (exe_mod) {
m_exe_file_spec = exe_mod->GetPlatformFileSpec();
- if (log)
- log->Printf("DYLDRendezvous::%s exe module executable path set: '%s'",
- __FUNCTION__, m_exe_file_spec.GetCString());
+ LLDB_LOGF(log, "DYLDRendezvous::%s exe module executable path set: '%s'",
+ __FUNCTION__, m_exe_file_spec.GetCString());
} else {
- if (log)
- log->Printf("DYLDRendezvous::%s cannot cache exe module path: null "
- "executable module pointer",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "DYLDRendezvous::%s cannot cache exe module path: null "
+ "executable module pointer",
+ __FUNCTION__);
}
}
}
@@ -133,17 +126,16 @@ bool DYLDRendezvous::Resolve() {
address_size = m_process->GetAddressByteSize();
padding = address_size - word_size;
- if (log)
- log->Printf("DYLDRendezvous::%s address size: %" PRIu64
- ", padding %" PRIu64,
- __FUNCTION__, uint64_t(address_size), uint64_t(padding));
+ LLDB_LOGF(log,
+ "DYLDRendezvous::%s address size: %" PRIu64 ", padding %" PRIu64,
+ __FUNCTION__, uint64_t(address_size), uint64_t(padding));
if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
cursor = info_addr = ResolveRendezvousAddress(m_process);
else
cursor = info_addr = m_rendezvous_addr;
- if (log)
- log->Printf("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor);
+ LLDB_LOGF(log, "DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__,
+ cursor);
if (cursor == LLDB_INVALID_ADDRESS)
return false;
@@ -168,7 +160,10 @@ bool DYLDRendezvous::Resolve() {
m_previous = m_current;
m_current = info;
- if (UpdateSOEntries(true))
+ if (m_current.map_addr == 0)
+ return false;
+
+ if (UpdateSOEntriesFromRemote())
return true;
return UpdateSOEntries();
@@ -178,53 +173,91 @@ bool DYLDRendezvous::IsValid() {
return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
}
-bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
- SOEntry entry;
- LoadedModuleInfoList module_list;
+DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const {
+ switch (m_current.state) {
+
+ case eConsistent:
+ switch (m_previous.state) {
+ // When the previous and current states are consistent this is the first
+ // time we have been asked to update. Just take a snapshot of the
+ // currently loaded modules.
+ case eConsistent:
+ return eTakeSnapshot;
+ // If we are about to add or remove a shared object clear out the current
+ // state and take a snapshot of the currently loaded images.
+ case eAdd:
+ return eAddModules;
+ case eDelete:
+ return eRemoveModules;
+ }
+ break;
- // If we can't get the SO info from the remote, return failure.
- if (fromRemote && m_process->LoadModules(module_list) == 0)
- return false;
+ case eAdd:
+ case eDelete:
+ // Some versions of the android dynamic linker might send two
+ // notifications with state == eAdd back to back. Ignore them until we
+ // get an eConsistent notification.
+ if (!(m_previous.state == eConsistent ||
+ (m_previous.state == eAdd && m_current.state == eDelete)))
+ return eNoAction;
+
+ return eTakeSnapshot;
+ }
+
+ return eNoAction;
+}
+
+bool DYLDRendezvous::UpdateSOEntriesFromRemote() {
+ auto action = GetAction();
- if (!fromRemote && m_current.map_addr == 0)
+ if (action == eNoAction)
return false;
- // When the previous and current states are consistent this is the first time
- // we have been asked to update. Just take a snapshot of the currently
- // loaded modules.
- if (m_previous.state == eConsistent && m_current.state == eConsistent)
- return fromRemote ? SaveSOEntriesFromRemote(module_list)
- : TakeSnapshot(m_soentries);
-
- // If we are about to add or remove a shared object clear out the current
- // state and take a snapshot of the currently loaded images.
- if (m_current.state == eAdd || m_current.state == eDelete) {
- // Some versions of the android dynamic linker might send two notifications
- // with state == eAdd back to back. Ignore them until we get an eConsistent
- // notification.
- if (!(m_previous.state == eConsistent ||
- (m_previous.state == eAdd && m_current.state == eDelete)))
- return false;
+ if (action == eTakeSnapshot) {
+ m_added_soentries.clear();
+ m_removed_soentries.clear();
+ // We already have the loaded list from the previous update so no need to
+ // find all the modules again.
+ if (!m_loaded_modules.m_list.empty())
+ return true;
+ }
+
+ llvm::Expected<LoadedModuleInfoList> module_list =
+ m_process->GetLoadedModuleList();
+ if (!module_list) {
+ llvm::consumeError(module_list.takeError());
+ return false;
+ }
+ switch (action) {
+ case eTakeSnapshot:
m_soentries.clear();
- if (fromRemote)
- return SaveSOEntriesFromRemote(module_list);
+ return SaveSOEntriesFromRemote(*module_list);
+ case eAddModules:
+ return AddSOEntriesFromRemote(*module_list);
+ case eRemoveModules:
+ return RemoveSOEntriesFromRemote(*module_list);
+ case eNoAction:
+ return false;
+ }
+ llvm_unreachable("Fully covered switch above!");
+}
+bool DYLDRendezvous::UpdateSOEntries() {
+ switch (GetAction()) {
+ case eTakeSnapshot:
+ m_soentries.clear();
m_added_soentries.clear();
m_removed_soentries.clear();
return TakeSnapshot(m_soentries);
+ case eAddModules:
+ return AddSOEntries();
+ case eRemoveModules:
+ return RemoveSOEntries();
+ case eNoAction:
+ return false;
}
- assert(m_current.state == eConsistent);
-
- // Otherwise check the previous state to determine what to expect and update
- // accordingly.
- if (m_previous.state == eAdd)
- return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries();
- else if (m_previous.state == eDelete)
- return fromRemote ? RemoveSOEntriesFromRemote(module_list)
- : RemoveSOEntries();
-
- return false;
+ llvm_unreachable("Fully covered switch above!");
}
bool DYLDRendezvous::FillSOEntryFromModuleInfo(
@@ -255,7 +288,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo(
}
bool DYLDRendezvous::SaveSOEntriesFromRemote(
- LoadedModuleInfoList &module_list) {
+ const LoadedModuleInfoList &module_list) {
for (auto const &modInfo : module_list.m_list) {
SOEntry entry;
if (!FillSOEntryFromModuleInfo(modInfo, entry))
@@ -270,7 +303,8 @@ bool DYLDRendezvous::SaveSOEntriesFromRemote(
return true;
}
-bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
+bool DYLDRendezvous::AddSOEntriesFromRemote(
+ const LoadedModuleInfoList &module_list) {
for (auto const &modInfo : module_list.m_list) {
bool found = false;
for (auto const &existing : m_loaded_modules.m_list) {
@@ -288,8 +322,10 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
return false;
// Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
+ if (!SOEntryIsMainExecutable(entry)) {
m_soentries.push_back(entry);
+ m_added_soentries.push_back(entry);
+ }
}
m_loaded_modules = module_list;
@@ -297,7 +333,7 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
}
bool DYLDRendezvous::RemoveSOEntriesFromRemote(
- LoadedModuleInfoList &module_list) {
+ const LoadedModuleInfoList &module_list) {
for (auto const &existing : m_loaded_modules.m_list) {
bool found = false;
for (auto const &modInfo : module_list.m_list) {
@@ -321,6 +357,7 @@ bool DYLDRendezvous::RemoveSOEntriesFromRemote(
return false;
m_soentries.erase(pos);
+ m_removed_soentries.push_back(entry);
}
}
@@ -521,9 +558,10 @@ bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field,
Target &target = m_process->GetTarget();
SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
- eSymbolTypeAny, list))
- return false;
+ target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list);
+ if (list.IsEmpty())
+ return false;
Address address = list[0].symbol->GetAddress();
addr_t addr = address.GetLoadAddress(&target);
@@ -569,16 +607,16 @@ void DYLDRendezvous::DumpToLog(Log *log) const {
return;
log->PutCString("DYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent)
- ? "consistent"
- : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
- : "unknown");
+ LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress());
+ LLDB_LOGF(log, " Version: %" PRIu64, GetVersion());
+ LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress());
+ LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress());
+ LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase());
+ LLDB_LOGF(log, " State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add"
+ : (state == eDelete) ? "delete" : "unknown");
iterator I = begin();
iterator E = end();
@@ -587,11 +625,11 @@ void DYLDRendezvous::DumpToLog(Log *log) const {
log->PutCString("DYLDRendezvous SOEntries:");
for (int i = 1; I != E; ++I, ++i) {
- log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
+ LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->file_spec.GetCString());
+ LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr);
+ LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr);
+ LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr);
+ LLDB_LOGF(log, " Next : %" PRIx64, I->next);
+ LLDB_LOGF(log, " Prev : %" PRIx64, I->prev);
}
}
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 993e62f5e9f9..536eeeaaf334 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -222,16 +222,20 @@ protected:
/// Updates the current set of SOEntries, the set of added entries, and the
/// set of removed entries.
- bool UpdateSOEntries(bool fromRemote = false);
+ bool UpdateSOEntries();
+
+ /// Same as UpdateSOEntries but it gets the list of loaded modules from the
+ /// remote debug server (faster when supported).
+ bool UpdateSOEntriesFromRemote();
bool FillSOEntryFromModuleInfo(
LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry);
- bool SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool SaveSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
- bool AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool AddSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
- bool RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool RemoveSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
bool AddSOEntries();
@@ -248,6 +252,17 @@ protected:
enum PThreadField { eSize, eNElem, eOffset };
bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
+
+ enum RendezvousAction {
+ eNoAction,
+ eTakeSnapshot,
+ eAddModules,
+ eRemoveModules
+ };
+
+ /// Returns the current action to be taken given the current and previous
+ /// state
+ RendezvousAction GetAction() const;
};
#endif
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index b55660899d0d..9d61c8feb923 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -85,32 +85,31 @@ DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
void DynamicLoaderPOSIXDYLD::DidAttach() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
- m_auxv = llvm::make_unique<AuxVector>(m_process->GetAuxvData());
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(
+ log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
+ __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
// ask the process if it can load any of its own modules
- m_process->LoadModules();
+ auto error = m_process->LoadModules();
+ LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}");
ModuleSP executable_sp = GetTargetExecutable();
ResolveExecutableModule(executable_sp);
// find the main process load offset
addr_t load_offset = ComputeLoadOffset();
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " executable '%s', load_offset 0x%" PRIx64,
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
- : "<null executable>",
- load_offset);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " executable '%s', load_offset 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
+ : "<null executable>",
+ load_offset);
EvalSpecialModulesStatus();
@@ -137,12 +136,12 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
ModuleList module_list;
module_list.Append(executable_sp);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " added executable '%s' to module load list",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- executable_sp->GetFileSpec().GetPath().c_str());
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " added executable '%s' to module load list",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp->GetFileSpec().GetPath().c_str());
UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
true);
@@ -151,14 +150,15 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
m_process->GetTarget().ModulesDidLoad(module_list);
if (log) {
- log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the "
- "modules that loaded:",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s told the target about the "
+ "modules that loaded:",
+ __FUNCTION__);
for (auto module_sp : module_list.Modules()) {
- log->Printf("-- [module] %s (pid %" PRIu64 ")",
- module_sp ? module_sp->GetFileSpec().GetPath().c_str()
- : "<null>",
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")",
+ module_sp ? module_sp->GetFileSpec().GetPath().c_str()
+ : "<null>",
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
}
}
}
@@ -174,13 +174,12 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
void DynamicLoaderPOSIXDYLD::DidLaunch() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
ModuleSP executable;
addr_t load_offset;
- m_auxv = llvm::make_unique<AuxVector>(m_process->GetAuxvData());
+ m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
executable = GetTargetExecutable();
load_offset = ComputeLoadOffset();
@@ -191,9 +190,8 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() {
module_list.Append(executable);
UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
- __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
+ __FUNCTION__);
if (!SetRendezvousBreakpoint()) {
// If we cannot establish rendezvous breakpoint right now we'll try again
@@ -227,22 +225,20 @@ void DynamicLoaderPOSIXDYLD::ProbeEntry() {
const addr_t entry = GetEntryPoint();
if (entry == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf(
- "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " GetEntryPoint() returned no address, not setting entry breakpoint",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(
+ log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned no address, not setting entry breakpoint",
+ __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
return;
}
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " GetEntryPoint() returned address 0x%" PRIx64
- ", setting entry breakpoint",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- entry);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned address 0x%" PRIx64
+ ", setting entry breakpoint",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, entry);
if (m_process) {
Breakpoint *const entry_break =
@@ -271,11 +267,10 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
DynamicLoaderPOSIXDYLD *const dyld_instance =
static_cast<DynamicLoaderPOSIXDYLD *>(baton);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
- __FUNCTION__,
- dyld_instance->m_process ? dyld_instance->m_process->GetID()
- : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
// Disable the breakpoint --- if a stop happens right after this, which we've
// seen on occasion, we don't want the breakpoint stepping thread-plan logic
@@ -287,22 +282,22 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
BreakpointSP breakpoint_sp =
dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
if (breakpoint_sp) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " disabling breakpoint id %" PRIu64,
- __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " disabling breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
breakpoint_sp->SetEnabled(false);
} else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " failed to find breakpoint for breakpoint id %" PRIu64,
- __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " failed to find breakpoint for breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
}
} else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
- " no Process instance! Cannot disable breakpoint",
- __FUNCTION__, break_id);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
+ " no Process instance! Cannot disable breakpoint",
+ __FUNCTION__, break_id);
}
dyld_instance->LoadAllCurrentModules();
@@ -393,23 +388,22 @@ bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
DynamicLoaderPOSIXDYLD *const dyld_instance =
static_cast<DynamicLoaderPOSIXDYLD *>(baton);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
- __FUNCTION__,
- dyld_instance->m_process ? dyld_instance->m_process->GetID()
- : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
dyld_instance->RefreshModules();
// Return true to stop the target, false to just let the target run.
const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " stop_when_images_change=%s",
- __FUNCTION__,
- dyld_instance->m_process ? dyld_instance->m_process->GetID()
- : LLDB_INVALID_PROCESS_ID,
- stop_when_images_change ? "true" : "false");
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " stop_when_images_change=%s",
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID,
+ stop_when_images_change ? "true" : "false");
return stop_when_images_change;
}
@@ -562,10 +556,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
LoadVDSO();
if (!m_rendezvous.Resolve()) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
- "rendezvous address",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
+ "rendezvous address",
+ __FUNCTION__);
return;
}
@@ -589,10 +583,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
module_list.Append(module_sp);
} else {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf(
- "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
- __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
+ LLDB_LOGF(
+ log,
+ "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
+ __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
}
}
@@ -697,12 +691,12 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
- ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
- module_sp->GetObjectName().AsCString(""), link_map, tp,
- (int64_t)modid, tls_block);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
+ module_sp->GetObjectName().AsCString(""), link_map, tp,
+ (int64_t)modid, tls_block);
if (tls_block == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
@@ -722,18 +716,17 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
ProcessInstanceInfo process_info;
if (!m_process->GetProcessInfo(process_info)) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
- "pid %" PRIu64,
- __FUNCTION__, m_process->GetID());
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
+ "pid %" PRIu64,
+ __FUNCTION__, m_process->GetID());
return;
}
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64
- ": %s",
- __FUNCTION__, m_process->GetID(),
- process_info.GetExecutableFile().GetPath().c_str());
+ LLDB_LOGF(
+ log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
+ __FUNCTION__, m_process->GetID(),
+ process_info.GetExecutableFile().GetPath().c_str());
ModuleSpec module_spec(process_info.GetExecutableFile(),
process_info.GetArchitecture());
@@ -748,10 +741,10 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
StreamString stream;
module_spec.Dump(stream);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
- "with module spec \"%s\": %s",
- __FUNCTION__, stream.GetData(), error.AsCString());
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
+ "with module spec \"%s\": %s",
+ __FUNCTION__, stream.GetData(), error.AsCString());
return;
}
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index fa3fbe0d9fa6..25ab30e9db9c 100644
--- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -122,38 +122,37 @@ lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) {
void DynamicLoaderWindowsDYLD::DidAttach() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
- ModuleSP executable = GetTargetExecutable();
+ ModuleSP executable = GetTargetExecutable();
- if (!executable.get())
- return;
+ if (!executable.get())
+ return;
- // Try to fetch the load address of the file from the process, since there
- // could be randomization of the load address.
- lldb::addr_t load_addr = GetLoadAddress(executable);
- if (load_addr == LLDB_INVALID_ADDRESS)
- return;
+ // Try to fetch the load address of the file from the process, since there
+ // could be randomization of the load address.
+ lldb::addr_t load_addr = GetLoadAddress(executable);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return;
- // Request the process base address.
- lldb::addr_t image_base = m_process->GetImageInfoAddress();
- if (image_base == load_addr)
- return;
+ // Request the process base address.
+ lldb::addr_t image_base = m_process->GetImageInfoAddress();
+ if (image_base == load_addr)
+ return;
- // Rebase the process's modules if there is a mismatch.
- UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);
+ // Rebase the process's modules if there is a mismatch.
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);
- ModuleList module_list;
- module_list.Append(executable);
- m_process->GetTarget().ModulesDidLoad(module_list);
- m_process->LoadModules();
+ ModuleList module_list;
+ module_list.Append(executable);
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ auto error = m_process->LoadModules();
+ LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");
}
void DynamicLoaderWindowsDYLD::DidLaunch() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
ModuleSP executable = GetTargetExecutable();
if (!executable.get())
@@ -167,7 +166,8 @@ void DynamicLoaderWindowsDYLD::DidLaunch() {
ModuleList module_list;
module_list.Append(executable);
m_process->GetTarget().ModulesDidLoad(module_list);
- m_process->LoadModules();
+ auto error = m_process->LoadModules();
+ LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");
}
}
diff --git a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
index 369f88327dd9..f33a713cc0b2 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
@@ -75,8 +75,6 @@ ASTDumper::ASTDumper(const CompilerType &compiler_type) {
const char *ASTDumper::GetCString() { return m_dump.c_str(); }
-void ASTDumper::ToSTDERR() { fprintf(stderr, "%s\n", m_dump.c_str()); }
-
void ASTDumper::ToLog(Log *log, const char *prefix) {
size_t len = m_dump.length() + 1;
@@ -92,7 +90,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) {
while (end) {
*end = '\0';
- log->Printf("%s%s", prefix, str);
+ LLDB_LOGF(log, "%s%s", prefix, str);
*end = '\n';
@@ -100,9 +98,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) {
end = strchr(str, '\n');
}
- log->Printf("%s%s", prefix, str);
+ LLDB_LOGF(log, "%s%s", prefix, str);
free(alloc);
}
-
-void ASTDumper::ToStream(lldb::StreamSP &stream) { stream->PutCString(m_dump); }
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 526ef90782ef..68eaad33f51c 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -58,13 +58,13 @@ void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) {
if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) {
if (log && log->GetVerbose()) {
if (named_decl->getIdentifier())
- log->Printf("TransformTopLevelDecl(%s)",
- named_decl->getIdentifier()->getNameStart());
+ LLDB_LOGF(log, "TransformTopLevelDecl(%s)",
+ named_decl->getIdentifier()->getNameStart());
else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
- log->Printf("TransformTopLevelDecl(%s)",
- method_decl->getSelector().getAsString().c_str());
+ LLDB_LOGF(log, "TransformTopLevelDecl(%s)",
+ method_decl->getSelector().getAsString().c_str());
else
- log->Printf("TransformTopLevelDecl(<complex>)");
+ LLDB_LOGF(log, "TransformTopLevelDecl(<complex>)");
}
if (m_top_level) {
@@ -130,7 +130,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) {
os.flush();
- log->Printf("Untransformed function AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Untransformed function AST:\n%s", s.c_str());
}
Stmt *function_body = function_decl->getBody();
@@ -146,7 +146,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) {
os.flush();
- log->Printf("Transformed function AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Transformed function AST:\n%s", s.c_str());
}
return ret;
@@ -170,7 +170,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult(
os.flush();
- log->Printf("Untransformed method AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Untransformed method AST:\n%s", s.c_str());
}
Stmt *method_body = MethodDecl->getBody();
@@ -190,7 +190,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult(
os.flush();
- log->Printf("Transformed method AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Transformed method AST:\n%s", s.c_str());
}
return ret;
@@ -308,8 +308,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
if (log) {
std::string s = expr_qual_type.getAsString();
- log->Printf("Last statement is an %s with type: %s",
- (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
+ LLDB_LOGF(log, "Last statement is an %s with type: %s",
+ (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
}
clang::VarDecl *result_decl = nullptr;
@@ -422,8 +422,7 @@ void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) {
ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent type %s\n", name_cs.GetCString());
+ LLDB_LOGF(log, "Recording persistent type %s\n", name_cs.GetCString());
m_decls.push_back(D);
}
@@ -443,8 +442,7 @@ void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) {
ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
+ LLDB_LOGF(log, "Recording persistent decl %s\n", name_cs.GetCString());
m_decls.push_back(D);
}
@@ -467,7 +465,7 @@ void ASTResultSynthesizer::CommitPersistentDecls() {
decl->dump(ss);
ss.flush();
- log->Printf("Couldn't commit persistent decl: %s\n", s.c_str());
+ LLDB_LOGF(log, "Couldn't commit persistent decl: %s\n", s.c_str());
}
continue;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index c5778f86bb62..372c2439ebf0 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -9,6 +9,7 @@
#include "ClangASTSource.h"
#include "ASTDumper.h"
+#include "ClangDeclVendor.h"
#include "ClangModulesDeclVendor.h"
#include "lldb/Core/Module.h"
@@ -18,7 +19,6 @@
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
@@ -74,14 +74,19 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
file_manager};
std::vector<clang::ExternalASTMerger::ImporterSource> sources;
for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) {
- if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>(
- module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) {
+ auto type_system_or_err =
+ module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS),
+ std::move(err), "Failed to get ClangASTContext");
+ } else if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>(
+ &type_system_or_err.get())) {
lldbassert(module_ast_ctx->getASTContext());
lldbassert(module_ast_ctx->getFileManager());
- sources.push_back({*module_ast_ctx->getASTContext(),
- *module_ast_ctx->getFileManager(),
- module_ast_ctx->GetOriginMap()
- });
+ sources.emplace_back(*module_ast_ctx->getASTContext(),
+ *module_ast_ctx->getFileManager(),
+ module_ast_ctx->GetOriginMap());
}
}
@@ -96,17 +101,14 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
if (!language_runtime)
break;
- DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor();
-
- if (!runtime_decl_vendor)
- break;
-
- sources.push_back(runtime_decl_vendor->GetImporterSource());
+ if (auto *runtime_decl_vendor = llvm::dyn_cast_or_null<ClangDeclVendor>(
+ language_runtime->GetDeclVendor())) {
+ sources.push_back(runtime_decl_vendor->GetImporterSource());
+ }
} while (false);
do {
- DeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor();
+ auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor();
if (!modules_decl_vendor)
break;
@@ -127,11 +129,9 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
*scratch_ast_context->getFileManager(),
scratch_ast_context->GetOriginMap()});
}
- while (false)
- ;
m_merger_up =
- llvm::make_unique<clang::ExternalASTMerger>(target, sources);
+ std::make_unique<clang::ExternalASTMerger>(target, sources);
} else {
m_ast_importer_sp->InstallMapCompleter(&ast_context, *this);
}
@@ -273,13 +273,13 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
unsigned int current_id = invocation_id++;
if (log) {
- log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing "
- "(TagDecl*)%p named %s",
- current_id, static_cast<void *>(m_ast_context),
- static_cast<void *>(tag_decl),
- tag_decl->getName().str().c_str());
+ LLDB_LOGF(log,
+ " CompleteTagDecl[%u] on (ASTContext*)%p Completing "
+ "(TagDecl*)%p named %s",
+ current_id, static_cast<void *>(m_ast_context),
+ static_cast<void *>(tag_decl), tag_decl->getName().str().c_str());
- log->Printf(" CTD[%u] Before:", current_id);
+ LLDB_LOGF(log, " CTD[%u] Before:", current_id);
ASTDumper dumper((Decl *)tag_decl);
dumper.ToLog(log, " [CTD] ");
}
@@ -301,10 +301,10 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
// We couldn't complete the type. Maybe there's a definition somewhere
// else that can be completed.
- if (log)
- log->Printf(" CTD[%u] Type could not be completed in the module in "
- "which it was first found.",
- current_id);
+ LLDB_LOGF(log,
+ " CTD[%u] Type could not be completed in the module in "
+ "which it was first found.",
+ current_id);
bool found = false;
@@ -316,9 +316,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (log && log->GetVerbose())
- log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
+ LLDB_LOGF(log, " CTD[%u] Inspecting namespace map %p (%d entries)",
+ current_id, static_cast<void *>(namespace_map.get()),
+ static_cast<int>(namespace_map->size()));
if (!namespace_map)
return;
@@ -326,10 +326,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e && !found; ++i) {
- if (log)
- log->Printf(" CTD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CTD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
TypeList types;
@@ -409,7 +408,7 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
}
if (log) {
- log->Printf(" [CTD] After:");
+ LLDB_LOGF(log, " [CTD] After:");
ASTDumper dumper((Decl *)tag_decl);
dumper.ToLog(log, " [CTD] ");
}
@@ -419,11 +418,12 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log) {
- log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing "
- "an ObjCInterfaceDecl named %s",
- static_cast<void *>(m_ast_context),
- interface_decl->getName().str().c_str());
- log->Printf(" [COID] Before:");
+ LLDB_LOGF(log,
+ " [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing "
+ "an ObjCInterfaceDecl named %s",
+ static_cast<void *>(m_ast_context),
+ interface_decl->getName().str().c_str());
+ LLDB_LOGF(log, " [COID] Before:");
ASTDumper dumper((Decl *)interface_decl);
dumper.ToLog(log, " [COID] ");
}
@@ -467,7 +467,7 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
CompleteType(interface_decl->getSuperClass());
if (log) {
- log->Printf(" [COID] After:");
+ LLDB_LOGF(log, " [COID] After:");
ASTDumper dumper((Decl *)interface_decl);
dumper.ToLog(log, " [COID] ");
}
@@ -554,20 +554,22 @@ void ClangASTSource::FindExternalLexicalDecls(
if (log) {
if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- log->Printf(
+ LLDB_LOGF(
+ log,
"FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p",
current_id, static_cast<void *>(m_ast_context),
context_named_decl->getNameAsString().c_str(),
context_decl->getDeclKindName(),
static_cast<const void *>(context_decl));
else if (context_decl)
- log->Printf(
- "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
+ LLDB_LOGF(
+ log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
current_id, static_cast<void *>(m_ast_context),
context_decl->getDeclKindName(),
static_cast<const void *>(context_decl));
else
- log->Printf(
+ LLDB_LOGF(
+ log,
"FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
current_id, static_cast<const void *>(m_ast_context));
}
@@ -580,9 +582,9 @@ void ClangASTSource::FindExternalLexicalDecls(
return;
if (log) {
- log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:",
- current_id, static_cast<void *>(original_ctx),
- static_cast<void *>(original_decl));
+ LLDB_LOGF(
+ log, " FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id,
+ static_cast<void *>(original_ctx), static_cast<void *>(original_decl));
ASTDumper(original_decl).ToLog(log, " ");
}
@@ -626,13 +628,13 @@ void ClangASTSource::FindExternalLexicalDecls(
ASTDumper ast_dumper(decl);
if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context_decl))
- log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s",
- current_id, context_named_decl->getDeclKindName(),
- context_named_decl->getNameAsString().c_str(),
- decl->getDeclKindName(), ast_dumper.GetCString());
+ LLDB_LOGF(log, " FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s",
+ current_id, context_named_decl->getDeclKindName(),
+ context_named_decl->getNameAsString().c_str(),
+ decl->getDeclKindName(), ast_dumper.GetCString());
else
- log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id,
- decl->getDeclKindName(), ast_dumper.GetCString());
+ LLDB_LOGF(log, " FELD[%d] Adding lexical %sDecl %s", current_id,
+ decl->getDeclKindName(), ast_dumper.GetCString());
}
Decl *copied_decl = CopyDecl(decl);
@@ -645,6 +647,20 @@ void ClangASTSource::FindExternalLexicalDecls(
m_ast_importer_sp->RequireCompleteType(copied_field_type);
}
+ auto decl_context_non_const = const_cast<DeclContext *>(decl_context);
+
+ // The decl ended up in the wrong DeclContext. Let's fix that so
+ // the decl we copied will actually be found.
+ // FIXME: This is a horrible hack that shouldn't be necessary. However
+ // it seems our current setup sometimes fails to copy decls to the right
+ // place. See rdar://55129537.
+ if (copied_decl->getDeclContext() != decl_context) {
+ assert(copied_decl->getDeclContext()->containsDecl(copied_decl));
+ copied_decl->getDeclContext()->removeDecl(copied_decl);
+ copied_decl->setDeclContext(decl_context_non_const);
+ assert(!decl_context_non_const->containsDecl(copied_decl));
+ decl_context_non_const->addDeclInternal(copied_decl);
+ }
} else {
SkippedDecls = true;
}
@@ -678,22 +694,25 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
if (log) {
if (!context.m_decl_context)
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in a NULL DeclContext",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ LLDB_LOGF(log,
+ "ClangASTSource::FindExternalVisibleDecls[%u] on "
+ "(ASTContext*)%p for '%s' in a NULL DeclContext",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString());
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in '%s'",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(),
- context_named_decl->getNameAsString().c_str());
+ LLDB_LOGF(log,
+ "ClangASTSource::FindExternalVisibleDecls[%u] on "
+ "(ASTContext*)%p for '%s' in '%s'",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString(),
+ context_named_decl->getNameAsString().c_str());
else
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in a '%s'",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(), context.m_decl_context->getDeclKindName());
+ LLDB_LOGF(log,
+ "ClangASTSource::FindExternalVisibleDecls[%u] on "
+ "(ASTContext*)%p for '%s' in a '%s'",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString(), context.m_decl_context->getDeclKindName());
}
if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context)
@@ -723,9 +742,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr;
if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
+ LLDB_LOGF(log, " CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
+ current_id, static_cast<void *>(namespace_map.get()),
+ static_cast<int>(namespace_map->size()));
if (!namespace_map)
return;
@@ -733,10 +752,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e; ++i) {
- if (log)
- log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CAS::FEVD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
FindExternalVisibleDecls(context, i->first, i->second, current_id);
}
@@ -748,8 +766,7 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
} else {
CompilerDeclContext namespace_decl;
- if (log)
- log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
+ LLDB_LOGF(log, " CAS::FEVD[%u] Searching the root namespace", current_id);
FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
current_id);
@@ -757,10 +774,10 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
if (!context.m_namespace_map->empty()) {
if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
- current_id,
- static_cast<void *>(context.m_namespace_map.get()),
- static_cast<int>(context.m_namespace_map->size()));
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] Registering namespace map %p (%d entries)",
+ current_id, static_cast<void *>(context.m_namespace_map.get()),
+ static_cast<int>(context.m_namespace_map->size()));
NamespaceDecl *clang_namespace_decl =
AddNamespace(context, context.m_namespace_map);
@@ -807,21 +824,17 @@ void ClangASTSource::FindExternalVisibleDecls(
if (module_sp && namespace_decl) {
CompilerDeclContext found_namespace_decl;
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
-
- if (symbol_vendor) {
- found_namespace_decl =
- symbol_vendor->FindNamespace(name, &namespace_decl);
+ if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
+ found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
if (found_namespace_decl) {
context.m_namespace_map->push_back(
std::pair<lldb::ModuleSP, CompilerDeclContext>(
module_sp, found_namespace_decl));
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
}
}
} else if (!HasMerger()) {
@@ -836,23 +849,21 @@ void ClangASTSource::FindExternalVisibleDecls(
CompilerDeclContext found_namespace_decl;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ SymbolFile *symbol_file = image->GetSymbolFile();
- if (!symbol_vendor)
+ if (!symbol_file)
continue;
- found_namespace_decl =
- symbol_vendor->FindNamespace(name, &namespace_decl);
+ found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
if (found_namespace_decl) {
context.m_namespace_map->push_back(
std::pair<lldb::ModuleSP, CompilerDeclContext>(
image, found_namespace_decl));
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
}
}
}
@@ -878,9 +889,9 @@ void ClangASTSource::FindExternalVisibleDecls(
if (log) {
const char *name_string = type_sp->GetName().GetCString();
- log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
- current_id, name.GetCString(),
- (name_string ? name_string : "<anonymous>"));
+ LLDB_LOGF(log, " CAS::FEVD[%u] Matching type found for \"%s\": %s",
+ current_id, name.GetCString(),
+ (name_string ? name_string : "<anonymous>"));
}
CompilerType full_type = type_sp->GetFullCompilerType();
@@ -888,8 +899,8 @@ void ClangASTSource::FindExternalVisibleDecls(
CompilerType copied_clang_type(GuardedCopyType(full_type));
if (!copied_clang_type) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type", current_id);
+ LLDB_LOGF(log, " CAS::FEVD[%u] - Couldn't export a type",
+ current_id);
continue;
}
@@ -915,9 +926,10 @@ void ClangASTSource::FindExternalVisibleDecls(
break;
if (log) {
- log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in "
- "the modules",
- current_id, name.GetCString());
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] Matching entity found for \"%s\" in "
+ "the modules",
+ current_id, name.GetCString());
}
clang::NamedDecl *const decl_from_modules = decls[0];
@@ -930,10 +942,10 @@ void ClangASTSource::FindExternalVisibleDecls(
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
if (!copied_named_decl) {
- if (log)
- log->Printf(
- " CAS::FEVD[%u] - Couldn't export a type from the modules",
- current_id);
+ LLDB_LOGF(
+ log,
+ " CAS::FEVD[%u] - Couldn't export a type from the modules",
+ current_id);
break;
}
@@ -971,11 +983,13 @@ void ClangASTSource::FindExternalVisibleDecls(
uint32_t max_matches = 1;
std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(name, append, max_matches, decls))
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
break;
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
current_id, name.GetCString());
}
@@ -985,10 +999,9 @@ void ClangASTSource::FindExternalVisibleDecls(
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
if (!copied_named_decl) {
- if (log)
- log->Printf(
- " CAS::FEVD[%u] - Couldn't export a type from the runtime",
- current_id);
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] - Couldn't export a type from the runtime",
+ current_id);
break;
}
@@ -1126,8 +1139,8 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
if (log) {
ASTDumper dumper((Decl *)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOMD[%d] found (%s) %s", current_id, log_info,
+ dumper.GetCString());
}
context.AddNamedDecl(copied_method_decl);
@@ -1205,17 +1218,16 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ConstString selector_name(ss.GetString());
- if (log)
- log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p "
- "for selector [%s %s]",
- current_id, static_cast<void *>(m_ast_context),
- interface_decl->getNameAsString().c_str(),
- selector_name.AsCString());
+ LLDB_LOGF(log,
+ "ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p "
+ "for selector [%s %s]",
+ current_id, static_cast<void *>(m_ast_context),
+ interface_decl->getNameAsString().c_str(),
+ selector_name.AsCString());
SymbolContextList sc_list;
const bool include_symbols = false;
const bool include_inlines = false;
- const bool append = false;
std::string interface_name = interface_decl->getNameAsString();
@@ -1225,9 +1237,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ms.Flush();
ConstString instance_method_name(ms.GetString());
+ sc_list.Clear();
m_target->GetImages().FindFunctions(
instance_method_name, lldb::eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
if (sc_list.GetSize())
break;
@@ -1237,9 +1250,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ms.Flush();
ConstString class_method_name(ms.GetString());
+ sc_list.Clear();
m_target->GetImages().FindFunctions(
class_method_name, lldb::eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
if (sc_list.GetSize())
break;
@@ -1252,7 +1266,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
m_target->GetImages().FindFunctions(
selector_name, lldb::eFunctionNameTypeSelector, include_symbols,
- include_inlines, append, candidate_sc_list);
+ include_inlines, candidate_sc_list);
for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) {
SymbolContext candidate_sc;
@@ -1331,8 +1345,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (log) {
ASTDumper dumper((Decl *)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOMD[%d] found (in symbols) %s", current_id,
+ dumper.GetCString());
}
context.AddNamedDecl(copied_method_decl);
@@ -1360,11 +1374,11 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (complete_interface_decl == interface_decl)
break; // already checked this one
- if (log)
- log->Printf("CAS::FOPD[%d] trying origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<void *>(complete_interface_decl),
- static_cast<void *>(&complete_iface_decl->getASTContext()));
+ LLDB_LOGF(log,
+ "CAS::FOPD[%d] trying origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id, static_cast<void *>(complete_interface_decl),
+ static_cast<void *>(&complete_iface_decl->getASTContext()));
FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
"in debug info");
@@ -1423,7 +1437,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
uint32_t max_matches = 1;
std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(interface_name, append, max_matches, decls))
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(interface_name, append, max_matches,
+ decls))
break;
ObjCInterfaceDecl *runtime_interface_decl =
@@ -1462,8 +1478,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
if (parser_property_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_property_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id,
+ dumper.GetCString());
}
context.AddNamedDecl(parser_property_decl.decl);
@@ -1480,8 +1496,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
if (parser_ivar_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_ivar_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id,
+ dumper.GetCString());
}
context.AddNamedDecl(parser_ivar_decl.decl);
@@ -1505,23 +1521,23 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
- if (log)
- log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on "
- "(ASTContext*)%p for '%s.%s'",
- current_id, static_cast<void *>(m_ast_context),
- parser_iface_decl->getNameAsString().c_str(),
- context.m_decl_name.getAsString().c_str());
+ LLDB_LOGF(log,
+ "ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on "
+ "(ASTContext*)%p for '%s.%s'",
+ current_id, static_cast<void *>(m_ast_context),
+ parser_iface_decl->getNameAsString().c_str(),
+ context.m_decl_name.getAsString().c_str());
if (FindObjCPropertyAndIvarDeclsWithOrigin(
current_id, context, *this, origin_iface_decl))
return;
- if (log)
- log->Printf("CAS::FOPD[%d] couldn't find the property on origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching "
- "elsewhere...",
- current_id, static_cast<const void *>(origin_iface_decl.decl),
- static_cast<void *>(&origin_iface_decl->getASTContext()));
+ LLDB_LOGF(log,
+ "CAS::FOPD[%d] couldn't find the property on origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching "
+ "elsewhere...",
+ current_id, static_cast<const void *>(origin_iface_decl.decl),
+ static_cast<void *>(&origin_iface_decl->getASTContext()));
SymbolContext null_sc;
TypeList type_list;
@@ -1542,12 +1558,11 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (complete_iface_decl.decl == origin_iface_decl.decl)
break; // already checked this one
- if (log)
- log->Printf("CAS::FOPD[%d] trying origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void *>(complete_iface_decl.decl),
- static_cast<void *>(&complete_iface_decl->getASTContext()));
+ LLDB_LOGF(log,
+ "CAS::FOPD[%d] trying origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id, static_cast<const void *>(complete_iface_decl.decl),
+ static_cast<void *>(&complete_iface_decl->getASTContext()));
FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
complete_iface_decl);
@@ -1578,13 +1593,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_modules.IsValid())
break;
- if (log)
- log->Printf(
- "CAS::FOPD[%d] trying module "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void *>(interface_decl_from_modules.decl),
- static_cast<void *>(&interface_decl_from_modules->getASTContext()));
+ LLDB_LOGF(
+ log,
+ "CAS::FOPD[%d] trying module "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id, static_cast<const void *>(interface_decl_from_modules.decl),
+ static_cast<void *>(&interface_decl_from_modules->getASTContext()));
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
interface_decl_from_modules))
@@ -1614,7 +1628,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
uint32_t max_matches = 1;
std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(class_name, append, max_matches, decls))
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(class_name, append, max_matches, decls))
break;
DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(
@@ -1623,13 +1638,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_runtime.IsValid())
break;
- if (log)
- log->Printf(
- "CAS::FOPD[%d] trying runtime "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void *>(interface_decl_from_runtime.decl),
- static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
+ LLDB_LOGF(
+ log,
+ "CAS::FOPD[%d] trying runtime "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id, static_cast<const void *>(interface_decl_from_runtime.decl),
+ static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
if (FindObjCPropertyAndIvarDeclsWithOrigin(
current_id, context, *this, interface_decl_from_runtime))
@@ -1729,12 +1743,12 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p "
- "[name = '%s']",
- current_id, static_cast<void *>(m_ast_context),
- static_cast<const void *>(record),
- record->getNameAsString().c_str());
+ LLDB_LOGF(log,
+ "LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p "
+ "[name = '%s']",
+ current_id, static_cast<void *>(m_ast_context),
+ static_cast<const void *>(record),
+ record->getNameAsString().c_str());
DeclFromParser<const RecordDecl> parser_record(record);
DeclFromUser<const RecordDecl> origin_record(
@@ -1798,24 +1812,25 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
m_ast_context->getCharWidth();
if (log) {
- log->Printf("LRT[%u] returned:", current_id);
- log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id,
- static_cast<const void *>(origin_record.decl));
- log->Printf("LRT[%u] Size = %" PRId64, current_id, size);
- log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment);
- log->Printf("LRT[%u] Fields:", current_id);
+ LLDB_LOGF(log, "LRT[%u] returned:", current_id);
+ LLDB_LOGF(log, "LRT[%u] Original = (RecordDecl*)%p", current_id,
+ static_cast<const void *>(origin_record.decl));
+ LLDB_LOGF(log, "LRT[%u] Size = %" PRId64, current_id, size);
+ LLDB_LOGF(log, "LRT[%u] Alignment = %" PRId64, current_id, alignment);
+ LLDB_LOGF(log, "LRT[%u] Fields:", current_id);
for (RecordDecl::field_iterator fi = record->field_begin(),
fe = record->field_end();
fi != fe; ++fi) {
- log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64
- " bits",
- current_id, static_cast<void *>(*fi),
- fi->getNameAsString().c_str(), field_offsets[*fi]);
+ LLDB_LOGF(log,
+ "LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64
+ " bits",
+ current_id, static_cast<void *>(*fi),
+ fi->getNameAsString().c_str(), field_offsets[*fi]);
}
DeclFromParser<const CXXRecordDecl> parser_cxx_record =
DynCast<const CXXRecordDecl>(parser_record);
if (parser_cxx_record.IsValid()) {
- log->Printf("LRT[%u] Bases:", current_id);
+ LLDB_LOGF(log, "LRT[%u] Bases:", current_id);
for (CXXRecordDecl::base_class_const_iterator
bi = parser_cxx_record->bases_begin(),
be = parser_cxx_record->bases_end();
@@ -1828,7 +1843,8 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
DeclFromParser<CXXRecordDecl> base_cxx_record =
DynCast<CXXRecordDecl>(base_record);
- log->Printf(
+ LLDB_LOGF(
+ log,
"LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64
" chars",
current_id, (is_virtual ? "Virtual " : ""),
@@ -1839,7 +1855,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
: base_offsets[base_cxx_record.decl].getQuantity()));
}
} else {
- log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
+ LLDB_LOGF(log, "LRD[%u] Not a CXXRecord, so no bases", current_id);
}
}
@@ -1856,16 +1872,18 @@ void ClangASTSource::CompleteNamespaceMap(
if (log) {
if (parent_map && parent_map->size())
- log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
- "namespace %s in namespace %s",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(),
- parent_map->begin()->second.GetName().AsCString());
+ LLDB_LOGF(log,
+ "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
+ "namespace %s in namespace %s",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString(),
+ parent_map->begin()->second.GetName().AsCString());
else
- log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
- "namespace %s",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ LLDB_LOGF(log,
+ "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
+ "namespace %s",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString());
}
if (parent_map) {
@@ -1877,13 +1895,13 @@ void ClangASTSource::CompleteNamespaceMap(
lldb::ModuleSP module_sp = i->first;
CompilerDeclContext module_parent_namespace_decl = i->second;
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
+ SymbolFile *symbol_file = module_sp->GetSymbolFile();
- if (!symbol_vendor)
+ if (!symbol_file)
continue;
found_namespace_decl =
- symbol_vendor->FindNamespace(name, &module_parent_namespace_decl);
+ symbol_file->FindNamespace(name, &module_parent_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1891,10 +1909,9 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
module_sp, found_namespace_decl));
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
}
} else {
const ModuleList &target_images = m_target->GetImages();
@@ -1910,13 +1927,13 @@ void ClangASTSource::CompleteNamespaceMap(
CompilerDeclContext found_namespace_decl;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ SymbolFile *symbol_file = image->GetSymbolFile();
- if (!symbol_vendor)
+ if (!symbol_file)
continue;
found_namespace_decl =
- symbol_vendor->FindNamespace(name, &null_namespace_decl);
+ symbol_file->FindNamespace(name, &null_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1924,10 +1941,9 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
image, found_namespace_decl));
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
}
}
}
@@ -2065,7 +2081,8 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
// seems to be generating bad types on occasion.
return CompilerType();
- return CompilerType(m_ast_context, copied_qual_type);
+ return CompilerType(ClangASTContext::GetASTContext(m_ast_context),
+ copied_qual_type.getAsOpaquePtr());
}
clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
@@ -2162,8 +2179,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
} else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Function type wasn't a FunctionProtoType");
+ LLDB_LOGF(log, "Function type wasn't a FunctionProtoType");
}
// If this is an operator (e.g. operator new or operator==), only insert the
@@ -2194,7 +2210,9 @@ clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
proto_info));
return AddFunDecl(
- CompilerType(m_ast_source.m_ast_context, generic_function_type), true);
+ CompilerType(ClangASTContext::GetASTContext(m_ast_source.m_ast_context),
+ generic_function_type.getAsOpaquePtr()),
+ true);
}
clang::NamedDecl *
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
new file mode 100644
index 000000000000..c59722b7b4f8
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
@@ -0,0 +1,30 @@
+//===-- ClangDeclVendor.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 "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Utility/ConstString.h"
+
+using namespace lldb_private;
+
+uint32_t ClangDeclVendor::FindDecls(ConstString name, bool append,
+ uint32_t max_matches,
+ std::vector<CompilerDecl> &decls) {
+ if (!append)
+ decls.clear();
+
+ std::vector<clang::NamedDecl *> named_decls;
+ uint32_t ret = FindDecls(name, /*append*/ false, max_matches, named_decls);
+ for (auto *named_decl : named_decls) {
+ decls.push_back(CompilerDecl(
+ ClangASTContext::GetASTContext(&named_decl->getASTContext()),
+ named_decl));
+ }
+ return ret;
+}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
new file mode 100644
index 000000000000..90b715f37cba
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
@@ -0,0 +1,50 @@
+//===-- ClangDeclVendor.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_ClangDeclVendor_h_
+#define liblldb_ClangDeclVendor_h_
+
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/DeclVendor.h"
+
+#include "clang/AST/ExternalASTMerger.h"
+
+namespace lldb_private {
+
+// A clang specialized extension to DeclVendor.
+class ClangDeclVendor : public DeclVendor {
+public:
+ ClangDeclVendor(DeclVendorKind kind) : DeclVendor(kind) {}
+
+ virtual ~ClangDeclVendor() {}
+
+ /// Interface for ExternalASTMerger. Returns an ImporterSource allowing type
+ /// completion.
+ ///
+ /// \return
+ /// An ImporterSource for this ClangDeclVendor.
+ virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0;
+
+ uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
+ std::vector<CompilerDecl> &decls) override;
+
+ virtual uint32_t FindDecls(ConstString name, bool append,
+ uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) = 0;
+
+ static bool classof(const DeclVendor *vendor) {
+ return vendor->GetKind() >= eClangDeclVendor &&
+ vendor->GetKind() < eLastClangDeclVendor;
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ClangDeclVendor);
+};
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
index db50c2aa3e90..48cd1c4b99fa 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
@@ -29,7 +29,7 @@ public:
return diag->getKind() == eDiagnosticOriginClang;
}
- ClangDiagnostic(const char *message, DiagnosticSeverity severity,
+ ClangDiagnostic(llvm::StringRef message, DiagnosticSeverity severity,
uint32_t compiler_id)
: Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id) {}
@@ -42,6 +42,7 @@ public:
}
const FixItList &FixIts() const { return m_fixit_vec; }
+private:
FixItList m_fixit_vec;
};
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index a49a7029e0d2..f4457fc1b740 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -180,98 +180,20 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
return ret;
}
-namespace {
-/// This class walks an AST and ensures that all DeclContexts defined inside the
-/// current source file are properly complete.
-///
-/// This is used to ensure that persistent types defined in the current source
-/// file migrate completely to the persistent AST context before they are
-/// reused. If that didn't happen, it would be impoossible to complete them
-/// because their origin would be gone.
-///
-/// The stragtegy used by this class is to check the SourceLocation (to be
-/// specific, the FileID) and see if it's the FileID for the current expression.
-/// Alternate strategies could include checking whether an ExternalASTMerger,
-/// set up to not have the current context as a source, can find an original for
-/// the type.
-class Completer : public clang::RecursiveASTVisitor<Completer> {
-private:
- clang::ASTImporter &m_exporter; /// Used to import Decl contents
- clang::FileID m_file; /// The file that's going away
- llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles
-
- bool ImportAndCheckCompletable(clang::Decl *decl) {
- (void)m_exporter.Import(decl);
- if (m_completed.count(decl))
- return false;
- if (!llvm::isa<DeclContext>(decl))
- return false;
- const clang::SourceLocation loc = decl->getLocation();
- if (!loc.isValid())
- return false;
- const clang::FileID file =
- m_exporter.getFromContext().getSourceManager().getFileID(loc);
- if (file != m_file)
- return false;
- // We are assuming the Decl was parsed in this very expression, so it
- // should not have external storage.
- lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
- return true;
- }
-
- void Complete(clang::Decl *decl) {
- m_completed.insert(decl);
- auto *decl_context = llvm::cast<DeclContext>(decl);
- (void)m_exporter.Import(decl);
- m_exporter.CompleteDecl(decl);
- for (Decl *child : decl_context->decls())
- if (ImportAndCheckCompletable(child))
- Complete(child);
- }
-
- void MaybeComplete(clang::Decl *decl) {
- if (ImportAndCheckCompletable(decl))
- Complete(decl);
- }
-
-public:
- Completer(clang::ASTImporter &exporter, clang::FileID file)
- : m_exporter(exporter), m_file(file) {}
-
- // Implements the RecursiveASTVisitor's core API. It is called on each Decl
- // that the RecursiveASTVisitor encounters, and returns true if the traversal
- // should continue.
- bool VisitDecl(clang::Decl *decl) {
- MaybeComplete(decl);
- return true;
- }
-};
-}
-
-static void CompleteAllDeclContexts(clang::ASTImporter &exporter,
- clang::FileID file,
- clang::QualType root) {
- clang::QualType canonical_type = root.getCanonicalType();
- if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) {
- Completer(exporter, file).TraverseDecl(tag_decl);
- } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>(
- canonical_type.getTypePtr())) {
- Completer(exporter, file).TraverseDecl(interface_type->getDecl());
- } else {
- Completer(exporter, file).TraverseType(canonical_type);
- }
-}
-
static clang::QualType ExportAllDeclaredTypes(
- clang::ExternalASTMerger &merger,
+ clang::ExternalASTMerger &parent_merger, clang::ExternalASTMerger &merger,
clang::ASTContext &source, clang::FileManager &source_file_manager,
const clang::ExternalASTMerger::OriginMap &source_origin_map,
clang::FileID file, clang::QualType root) {
- clang::ExternalASTMerger::ImporterSource importer_source =
- { source, source_file_manager, source_origin_map };
+ // Mark the source as temporary to make sure all declarations from the
+ // AST are exported. Also add the parent_merger as the merger into the
+ // source AST so that the merger can track back any declarations from
+ // the persistent ASTs we used as sources.
+ clang::ExternalASTMerger::ImporterSource importer_source(
+ source, source_file_manager, source_origin_map, /*Temporary*/ true,
+ &parent_merger);
merger.AddSources(importer_source);
clang::ASTImporter &exporter = merger.ImporterForOrigin(source);
- CompleteAllDeclContexts(exporter, file, root);
llvm::Expected<clang::QualType> ret_or_error = exporter.Import(root);
merger.RemoveSources(importer_source);
if (ret_or_error) {
@@ -286,10 +208,10 @@ static clang::QualType ExportAllDeclaredTypes(
TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
ClangASTContext &source,
TypeFromParser parser_type) {
- assert (&target == m_target->GetScratchClangASTContext());
- assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
- assert (source.getASTContext() == m_ast_context);
-
+ assert(&target == m_target->GetScratchClangASTContext());
+ assert((TypeSystem *)&source == parser_type.GetTypeSystem());
+ assert(source.getASTContext() == m_ast_context);
+
if (m_ast_importer_sp) {
return TypeFromUser(m_ast_importer_sp->DeportType(
target.getASTContext(), source.getASTContext(),
@@ -299,13 +221,12 @@ TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
clang::FileID source_file =
source.getASTContext()->getSourceManager().getFileID(
source.getASTContext()->getTranslationUnitDecl()->getLocation());
- auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+ auto scratch_ast_context = static_cast<ClangASTContextForExpressions *>(
m_target->GetScratchClangASTContext());
clang::QualType exported_type = ExportAllDeclaredTypes(
- scratch_ast_context->GetMergerUnchecked(),
+ *m_merger_up.get(), scratch_ast_context->GetMergerUnchecked(),
*source.getASTContext(), *source.getFileManager(),
- m_merger_up->GetOrigins(),
- source_file,
+ m_merger_up->GetOrigins(), source_file,
clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
} else {
@@ -375,8 +296,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
TypeFromUser user_type = DeportType(*context, *ast, parser_type);
if (!user_type.GetOpaqueQualType()) {
- if (log)
- log->Printf("Persistent variable's type wasn't copied successfully");
+ LLDB_LOGF(log, "Persistent variable's type wasn't copied successfully");
return false;
}
@@ -415,8 +335,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
}
- if (log)
- log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
+ LLDB_LOGF(log, "Created persistent variable with flags 0x%hx", var->m_flags);
var->EnableParserVars(GetParserID());
@@ -458,10 +377,9 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!var)
return false;
- if (log)
- log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
- static_cast<const void *>(decl), name.GetCString(),
- var->GetName().GetCString());
+ LLDB_LOGF(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+ static_cast<const void *>(decl), name.GetCString(),
+ var->GetName().GetCString());
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
@@ -475,9 +393,8 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
// We already laid this out; do not touch
- if (log)
- log->Printf("Already placed at 0x%llx",
- (unsigned long long)jit_vars->m_offset);
+ LLDB_LOGF(log, "Already placed at 0x%llx",
+ (unsigned long long)jit_vars->m_offset);
}
llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
@@ -512,8 +429,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!err.Success())
return false;
- if (log)
- log->Printf("Placed at 0x%llx", (unsigned long long)offset);
+ LLDB_LOGF(log, "Placed at 0x%llx", (unsigned long long)offset);
jit_vars->m_offset =
offset; // TODO DoStructLayout() should not change this.
@@ -779,7 +695,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (GetImportInProgress()) {
if (log && log->GetVerbose())
- log->Printf("Ignoring a query during an import");
+ LLDB_LOGF(log, "Ignoring a query during an import");
return;
}
@@ -788,20 +704,23 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
if (!context.m_decl_context)
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a NULL DeclContext",
- current_id, name.GetCString());
+ LLDB_LOGF(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in a NULL DeclContext",
+ current_id, name.GetCString());
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in '%s'",
- current_id, name.GetCString(),
- context_named_decl->getNameAsString().c_str());
+ LLDB_LOGF(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in '%s'",
+ current_id, name.GetCString(),
+ context_named_decl->getNameAsString().c_str());
else
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a '%s'",
- current_id, name.GetCString(),
- context.m_decl_context->getDeclKindName());
+ LLDB_LOGF(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in a '%s'",
+ current_id, name.GetCString(),
+ context.m_decl_context->getDeclKindName());
}
if (const NamespaceDecl *namespace_context =
@@ -828,7 +747,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
current_id, static_cast<void *>(namespace_map.get()),
(int)namespace_map->size());
-
+
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e; ++i) {
@@ -848,7 +767,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
current_id);
}
-
+
ClangASTSource::FindExternalVisibleDecls(context);
}
@@ -922,9 +841,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
MaybeRegisterFunctionBody(parser_function_decl);
}
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id,
- name.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Found persistent decl %s", current_id,
+ name.GetCString());
context.AddNamedDecl(parser_named_decl);
} while (false);
@@ -979,8 +897,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
ASTDumper ast_dumper(class_qual_type);
- log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
+ current_id, ast_dumper.GetCString());
}
AddThisType(context, class_user_type, current_id);
@@ -1024,8 +942,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (pointee_type.IsValid()) {
if (log) {
ASTDumper ast_dumper(pointee_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_class: %s",
+ current_id, ast_dumper.GetCString());
}
AddThisType(context, pointee_type, current_id);
@@ -1048,7 +966,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
return;
AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
- current_id);
+ current_id);
m_struct_vars->m_object_pointer_type =
TypeFromUser(ctx_obj_ptr->GetCompilerType());
@@ -1096,8 +1014,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
ASTDumper ast_dumper(interface_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
}
AddOneType(context, class_user_type, current_id);
@@ -1157,8 +1075,9 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
ASTDumper ast_dumper(self_type->GetFullCompilerType());
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log,
+ " FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
}
TypeFromUser class_user_type(self_clang_type);
@@ -1222,9 +1141,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
reg_name));
if (reg_info) {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found register %s", current_id,
- reg_info->name);
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Found register %s", current_id,
+ reg_info->name);
AddOneRegister(context, reg_info, current_id);
}
@@ -1298,14 +1216,12 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
const bool include_inlines = false;
- const bool append = false;
-
+ sc_list.Clear();
if (namespace_decl && module_sp) {
const bool include_symbols = false;
module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
- include_symbols, include_inlines, append,
- sc_list);
+ include_symbols, include_inlines, sc_list);
} else if (target && !namespace_decl) {
const bool include_symbols = true;
@@ -1314,7 +1230,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
include_symbols, include_inlines,
- append, sc_list);
+ sc_list);
}
// If we found more than one function, see if we can use the frame's decl
@@ -1511,9 +1427,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
if (log) {
- log->Printf(" CAS::FEVD[%u] Matching function found for "
- "\"%s\" in the modules",
- current_id, name.GetCString());
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] Matching function found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
}
clang::Decl *copied_decl = CopyDecl(decl_from_modules);
@@ -1522,10 +1439,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
: nullptr;
if (!copied_function_decl) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
- "declaration from the modules",
- current_id);
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] - Couldn't export a function "
+ "declaration from the modules",
+ current_id);
break;
}
@@ -1538,9 +1455,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
context.m_found.function = true;
} else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
if (log) {
- log->Printf(" CAS::FEVD[%u] Matching variable found for "
- "\"%s\" in the modules",
- current_id, name.GetCString());
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] Matching variable found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
}
clang::Decl *copied_decl = CopyDecl(decl_from_modules);
@@ -1549,10 +1467,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
: nullptr;
if (!copied_var_decl) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
- "declaration from the modules",
- current_id);
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] - Couldn't export a variable "
+ "declaration from the modules",
+ current_id);
break;
}
@@ -1647,8 +1565,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
const_value_extractor.GetByteSize());
var_location.SetValueType(Value::eValueTypeHostAddress);
} else {
- if (log)
- log->Printf("Error evaluating constant variable: %s", err.AsCString());
+ LLDB_LOGF(log, "Error evaluating constant variable: %s", err.AsCString());
return false;
}
}
@@ -1656,9 +1573,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
CompilerType type_to_use = GuardedCopyType(var_clang_type);
if (!type_to_use) {
- if (log)
- log->Printf(
- "Couldn't copy a variable's type into the parser's AST context");
+ LLDB_LOGF(log,
+ "Couldn't copy a variable's type into the parser's AST context");
return false;
}
@@ -1751,9 +1667,10 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
if (log) {
ASTDumper orig_dumper(ut.GetOpaqueQualType());
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
- current_id, decl_name.c_str(), ast_dumper.GetCString(),
- orig_dumper.GetCString());
+ LLDB_LOGF(log,
+ " CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
+ current_id, decl_name.c_str(), ast_dumper.GetCString(),
+ orig_dumper.GetCString());
}
}
@@ -1768,9 +1685,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
TypeFromParser parser_type(GuardedCopyType(user_type));
if (!parser_type.GetOpaqueQualType()) {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s",
- current_id, pvar_sp->GetName().GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Couldn't import type for pvar %s",
+ current_id, pvar_sp->GetName().GetCString());
return;
}
@@ -1789,8 +1705,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
if (log) {
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
- pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
+ pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
}
}
@@ -1848,8 +1764,8 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
if (log) {
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id,
- decl_name.c_str(), ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Found variable %s, returned %s",
+ current_id, decl_name.c_str(), ast_dumper.GetCString());
}
}
@@ -1858,7 +1774,7 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
ClangASTContextForExpressions *scratch_ast_context =
- static_cast<ClangASTContextForExpressions*>(
+ static_cast<ClangASTContextForExpressions *>(
target->GetScratchClangASTContext());
for (size_t index = 0, num_entities = m_found_entities.GetSize();
@@ -1874,15 +1790,14 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
if (!var_decl) {
- if (log)
- log->Printf("Entity of unknown type does not have a VarDecl");
+ LLDB_LOGF(log, "Entity of unknown type does not have a VarDecl");
return false;
}
if (log) {
ASTDumper ast_dumper(const_cast<VarDecl *>(var_decl));
- log->Printf("Variable of unknown type now has Decl %s",
- ast_dumper.GetCString());
+ LLDB_LOGF(log, "Variable of unknown type now has Decl %s",
+ ast_dumper.GetCString());
}
QualType var_type = var_decl->getType();
@@ -1897,18 +1812,17 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
var_type.getAsOpaquePtr());
} else if (HasMerger()) {
copied_type = CopyTypeWithMerger(
- var_decl->getASTContext(),
- scratch_ast_context->GetMergerUnchecked(),
- var_type).getAsOpaquePtr();
+ var_decl->getASTContext(),
+ scratch_ast_context->GetMergerUnchecked(), var_type)
+ .getAsOpaquePtr();
} else {
lldbassert(0 && "No mechanism to copy a resolved unknown type!");
return false;
}
if (!copied_type) {
- if (log)
- log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
- "import the type for a variable");
+ LLDB_LOGF(log, "ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
+ "import the type for a variable");
return (bool)lldb::ExpressionVariableSP();
}
@@ -1939,9 +1853,8 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
m_ast_context, reg_info->encoding, reg_info->byte_size * 8);
if (!clang_type) {
- if (log)
- log->Printf(" Tried to add a type for %s, but couldn't get one",
- context.m_decl_name.getAsString().c_str());
+ LLDB_LOGF(log, " Tried to add a type for %s, but couldn't get one",
+ context.m_decl_name.getAsString().c_str());
return;
}
@@ -1969,9 +1882,9 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
if (log) {
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id,
- context.m_decl_name.getAsString().c_str(),
- ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%d] Added register %s, returned %s",
+ current_id, context.m_decl_name.getAsString().c_str(),
+ ast_dumper.GetCString());
}
}
@@ -2016,24 +1929,24 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
if (copied_function_template) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_template);
-
+
StreamString ss;
-
+
function->DumpSymbolContext(&ss);
-
+
log->Printf(" CEDM::FEVD[%u] Imported decl for function template"
" %s (description %s), returned %s",
current_id,
copied_function_template->getNameAsString().c_str(),
ss.GetData(), ast_dumper.GetCString());
}
-
+
context.AddNamedDecl(copied_function_template);
}
} else if (src_function_decl) {
if (clang::FunctionDecl *copied_function_decl =
llvm::dyn_cast_or_null<clang::FunctionDecl>(
- CopyDecl(src_function_decl))) {
+ CopyDecl(src_function_decl))) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
@@ -2041,19 +1954,20 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function->DumpSymbolContext(&ss);
- log->Printf(" CEDM::FEVD[%u] Imported decl for function %s "
- "(description %s), returned %s",
- current_id,
- copied_function_decl->getNameAsString().c_str(),
- ss.GetData(), ast_dumper.GetCString());
+ LLDB_LOGF(log,
+ " CEDM::FEVD[%u] Imported decl for function %s "
+ "(description %s), returned %s",
+ current_id,
+ copied_function_decl->getNameAsString().c_str(),
+ ss.GetData(), ast_dumper.GetCString());
}
context.AddNamedDecl(copied_function_decl);
return;
} else {
if (log) {
- log->Printf(" Failed to import the function decl for '%s'",
- src_function_decl->getName().str().c_str());
+ LLDB_LOGF(log, " Failed to import the function decl for '%s'",
+ src_function_decl->getName().str().c_str());
}
}
}
@@ -2082,7 +1996,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
if (!function_decl) {
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
" Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
function_type->GetName().GetCString(), function_type->GetID());
}
@@ -2092,10 +2007,11 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
} else {
// We failed to copy the type we found
if (log) {
- log->Printf(" Failed to import the function type '%s' {0x%8.8" PRIx64
- "} into the expression parser AST contenxt",
- function_type->GetName().GetCString(),
- function_type->GetID());
+ LLDB_LOGF(log,
+ " Failed to import the function type '%s' {0x%8.8" PRIx64
+ "} into the expression parser AST contenxt",
+ function_type->GetName().GetCString(),
+ function_type->GetID());
}
return;
@@ -2154,7 +2070,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
Address::DumpStyleResolvedDescription);
- log->Printf(
+ LLDB_LOGF(
+ log,
" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
current_id, (function ? "specific" : "generic"), decl_name.c_str(),
ss.GetData(), function_str.c_str());
@@ -2170,7 +2087,8 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
if (!copied_clang_type) {
if (log)
- log->Printf(
+ LLDB_LOGF(
+ log,
"ClangExpressionDeclMap::AddThisType - Couldn't import the type");
return;
@@ -2203,9 +2121,10 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
ASTDumper method_ast_dumper((clang::Decl *)method_decl);
ASTDumper type_ast_dumper(copied_clang_type);
- log->Printf(" CEDM::AddThisType Added function $__lldb_expr "
- "(description %s) for this type %s",
- method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
+ LLDB_LOGF(log,
+ " CEDM::AddThisType Added function $__lldb_expr "
+ "(description %s) for this type %s",
+ method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
}
}
@@ -2244,8 +2163,8 @@ void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log)
- log->Printf(
- "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+ LLDB_LOGF(
+ log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
return;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index 03b73e6be391..2711e90726e7 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -356,7 +356,7 @@ private:
/// Activate parser-specific variables
void EnableParserVars() {
if (!m_parser_vars.get())
- m_parser_vars = llvm::make_unique<ParserVars>();
+ m_parser_vars = std::make_unique<ParserVars>();
}
/// Deallocate parser-specific variables
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 7d13891ded8d..1422911d6546 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -105,16 +105,26 @@ using namespace lldb_private;
class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks {
ClangModulesDeclVendor &m_decl_vendor;
ClangPersistentVariables &m_persistent_vars;
+ clang::SourceManager &m_source_mgr;
StreamString m_error_stream;
bool m_has_errors = false;
public:
LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor,
- ClangPersistentVariables &persistent_vars)
- : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars) {}
+ ClangPersistentVariables &persistent_vars,
+ clang::SourceManager &source_mgr)
+ : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars),
+ m_source_mgr(source_mgr) {}
void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
const clang::Module * /*null*/) override {
+ // Ignore modules that are imported in the wrapper code as these are not
+ // loaded by the user.
+ llvm::StringRef filename =
+ m_source_mgr.getPresumedLoc(import_location).getFilename();
+ if (filename == ClangExpressionSourceCode::g_prefix_file_name)
+ return;
+
SourceModule module;
for (const std::pair<IdentifierInfo *, SourceLocation> &component : path)
@@ -137,12 +147,14 @@ public:
class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
public:
- ClangDiagnosticManagerAdapter()
- : m_passthrough(new clang::TextDiagnosticBuffer) {}
-
- ClangDiagnosticManagerAdapter(
- const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough)
- : m_passthrough(passthrough) {}
+ ClangDiagnosticManagerAdapter(DiagnosticOptions &opts) {
+ DiagnosticOptions *m_options = new DiagnosticOptions(opts);
+ m_options->ShowPresumedLoc = true;
+ m_options->ShowLevel = false;
+ m_os.reset(new llvm::raw_string_ostream(m_output));
+ m_passthrough.reset(
+ new clang::TextDiagnosticPrinter(*m_os, m_options, false));
+ }
void ResetManager(DiagnosticManager *manager = nullptr) {
m_manager = manager;
@@ -150,79 +162,92 @@ public:
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) override {
- if (m_manager) {
- llvm::SmallVector<char, 32> diag_str;
- Info.FormatDiagnostic(diag_str);
- diag_str.push_back('\0');
- const char *data = diag_str.data();
-
- lldb_private::DiagnosticSeverity severity;
- bool make_new_diagnostic = true;
-
- switch (DiagLevel) {
- case DiagnosticsEngine::Level::Fatal:
- case DiagnosticsEngine::Level::Error:
- severity = eDiagnosticSeverityError;
- break;
- case DiagnosticsEngine::Level::Warning:
- severity = eDiagnosticSeverityWarning;
- break;
- case DiagnosticsEngine::Level::Remark:
- case DiagnosticsEngine::Level::Ignored:
- severity = eDiagnosticSeverityRemark;
- break;
- case DiagnosticsEngine::Level::Note:
- m_manager->AppendMessageToDiagnostic(data);
- make_new_diagnostic = false;
- }
- if (make_new_diagnostic) {
- ClangDiagnostic *new_diagnostic =
- new ClangDiagnostic(data, severity, Info.getID());
- m_manager->AddDiagnostic(new_diagnostic);
-
- // Don't store away warning fixits, since the compiler doesn't have
- // enough context in an expression for the warning to be useful.
- // FIXME: Should we try to filter out FixIts that apply to our generated
- // code, and not the user's expression?
- if (severity == eDiagnosticSeverityError) {
- size_t num_fixit_hints = Info.getNumFixItHints();
- for (size_t i = 0; i < num_fixit_hints; i++) {
- const clang::FixItHint &fixit = Info.getFixItHint(i);
- if (!fixit.isNull())
- new_diagnostic->AddFixitHint(fixit);
- }
- }
+ if (!m_manager) {
+ // We have no DiagnosticManager before/after parsing but we still could
+ // receive diagnostics (e.g., by the ASTImporter failing to copy decls
+ // when we move the expression result ot the ScratchASTContext). Let's at
+ // least log these diagnostics until we find a way to properly render
+ // them and display them to the user.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ if (log) {
+ llvm::SmallVector<char, 32> diag_str;
+ Info.FormatDiagnostic(diag_str);
+ diag_str.push_back('\0');
+ const char *plain_diag = diag_str.data();
+ LLDB_LOG(log, "Received diagnostic outside parsing: {0}", plain_diag);
}
+ return;
}
+ // Render diagnostic message to m_output.
+ m_output.clear();
m_passthrough->HandleDiagnostic(DiagLevel, Info);
- }
+ m_os->flush();
- void FlushDiagnostics(DiagnosticsEngine &Diags) {
- m_passthrough->FlushDiagnostics(Diags);
- }
+ lldb_private::DiagnosticSeverity severity;
+ bool make_new_diagnostic = true;
+
+ switch (DiagLevel) {
+ case DiagnosticsEngine::Level::Fatal:
+ case DiagnosticsEngine::Level::Error:
+ severity = eDiagnosticSeverityError;
+ break;
+ case DiagnosticsEngine::Level::Warning:
+ severity = eDiagnosticSeverityWarning;
+ break;
+ case DiagnosticsEngine::Level::Remark:
+ case DiagnosticsEngine::Level::Ignored:
+ severity = eDiagnosticSeverityRemark;
+ break;
+ case DiagnosticsEngine::Level::Note:
+ m_manager->AppendMessageToDiagnostic(m_output);
+ make_new_diagnostic = false;
+ }
+ if (make_new_diagnostic) {
+ // ClangDiagnostic messages are expected to have no whitespace/newlines
+ // around them.
+ std::string stripped_output = llvm::StringRef(m_output).trim();
+
+ auto new_diagnostic = std::make_unique<ClangDiagnostic>(
+ stripped_output, severity, Info.getID());
+
+ // Don't store away warning fixits, since the compiler doesn't have
+ // enough context in an expression for the warning to be useful.
+ // FIXME: Should we try to filter out FixIts that apply to our generated
+ // code, and not the user's expression?
+ if (severity == eDiagnosticSeverityError) {
+ size_t num_fixit_hints = Info.getNumFixItHints();
+ for (size_t i = 0; i < num_fixit_hints; i++) {
+ const clang::FixItHint &fixit = Info.getFixItHint(i);
+ if (!fixit.isNull())
+ new_diagnostic->AddFixitHint(fixit);
+ }
+ }
- DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
- return new ClangDiagnosticManagerAdapter(m_passthrough);
+ m_manager->AddDiagnostic(std::move(new_diagnostic));
+ }
}
- clang::TextDiagnosticBuffer *GetPassthrough() { return m_passthrough.get(); }
+ clang::TextDiagnosticPrinter *GetPassthrough() { return m_passthrough.get(); }
private:
DiagnosticManager *m_manager = nullptr;
- std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough;
+ std::shared_ptr<clang::TextDiagnosticPrinter> m_passthrough;
+ /// Output stream of m_passthrough.
+ std::shared_ptr<llvm::raw_string_ostream> m_os;
+ /// Output string filled by m_os.
+ std::string m_output;
};
-static void
-SetupModuleHeaderPaths(CompilerInstance *compiler,
- std::vector<ConstString> include_directories,
- lldb::TargetSP target_sp) {
+static void SetupModuleHeaderPaths(CompilerInstance *compiler,
+ std::vector<std::string> include_directories,
+ lldb::TargetSP target_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts();
- for (ConstString dir : include_directories) {
- search_opts.AddPath(dir.AsCString(), frontend::System, false, true);
+ for (const std::string &dir : include_directories) {
+ search_opts.AddPath(dir, frontend::System, false, true);
LLDB_LOG(log, "Added user include dir: {0}", dir);
}
@@ -232,27 +257,9 @@ SetupModuleHeaderPaths(CompilerInstance *compiler,
search_opts.ModuleCachePath = module_cache.str();
LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str());
- FileSpec clang_resource_dir = GetClangResourceDir();
- std::string resource_dir = clang_resource_dir.GetPath();
- if (FileSystem::Instance().IsDirectory(resource_dir)) {
- search_opts.ResourceDir = resource_dir;
- std::string resource_include = resource_dir + "/include";
- search_opts.AddPath(resource_include, frontend::System, false, true);
-
- LLDB_LOG(log, "Added resource include dir: {0}", resource_include);
- }
+ search_opts.ResourceDir = GetClangResourceDir().GetPath();
search_opts.ImplicitModuleMaps = true;
-
- std::vector<std::string> system_include_directories =
- target_sp->GetPlatform()->GetSystemIncludeDirectories(
- lldb::eLanguageTypeC_plus_plus);
-
- for (const std::string &include_dir : system_include_directories) {
- search_opts.AddPath(include_dir, frontend::System, false, true);
-
- LLDB_LOG(log, "Added system include dir: {0}", include_dir);
- }
}
//===----------------------------------------------------------------------===//
@@ -261,10 +268,12 @@ SetupModuleHeaderPaths(CompilerInstance *compiler,
ClangExpressionParser::ClangExpressionParser(
ExecutionContextScope *exe_scope, Expression &expr,
- bool generate_debug_info, std::vector<ConstString> include_directories)
+ bool generate_debug_info, std::vector<std::string> include_directories,
+ std::string filename)
: ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(),
m_pp_callbacks(nullptr),
- m_include_directories(std::move(include_directories)) {
+ m_include_directories(std::move(include_directories)),
+ m_filename(std::move(filename)) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
// We can't compile expressions without a target. So if the exe_scope is
@@ -331,9 +340,8 @@ ClangExpressionParser::ClangExpressionParser(
if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) {
lang_rt = process_sp->GetLanguageRuntime(frame_lang);
- if (log)
- log->Printf("Frame has language of type %s",
- Language::GetNameForLanguageType(frame_lang));
+ LLDB_LOGF(log, "Frame has language of type %s",
+ Language::GetNameForLanguageType(frame_lang));
}
// 2. Configure the compiler with a set of default options that are
@@ -341,9 +349,8 @@ ClangExpressionParser::ClangExpressionParser(
if (target_arch.IsValid()) {
std::string triple = target_arch.GetTriple().str();
m_compiler->getTargetOpts().Triple = triple;
- if (log)
- log->Printf("Using %s as the target triple",
- m_compiler->getTargetOpts().Triple.c_str());
+ LLDB_LOGF(log, "Using %s as the target triple",
+ m_compiler->getTargetOpts().Triple.c_str());
} else {
// If we get here we don't have a valid target and just have to guess.
// Sometimes this will be ok to just use the host target triple (when we
@@ -352,9 +359,8 @@ ClangExpressionParser::ClangExpressionParser(
// the host triple. In such a case the language runtime should expose an
// overridden options set (3), below.
m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
- if (log)
- log->Printf("Using default target triple of %s",
- m_compiler->getTargetOpts().Triple.c_str());
+ LLDB_LOGF(log, "Using default target triple of %s",
+ m_compiler->getTargetOpts().Triple.c_str());
}
// Now add some special fixes for known architectures: Any arm32 iOS
// environment, but not on arm64
@@ -408,12 +414,13 @@ ClangExpressionParser::ClangExpressionParser(
auto target_info = TargetInfo::CreateTargetInfo(
m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts);
if (log) {
- log->Printf("Using SIMD alignment: %d", target_info->getSimdDefaultAlign());
- log->Printf("Target datalayout string: '%s'",
- target_info->getDataLayout().getStringRepresentation().c_str());
- log->Printf("Target ABI: '%s'", target_info->getABI().str().c_str());
- log->Printf("Target vector alignment: %d",
- target_info->getMaxVectorAlign());
+ LLDB_LOGF(log, "Using SIMD alignment: %d",
+ target_info->getSimdDefaultAlign());
+ LLDB_LOGF(log, "Target datalayout string: '%s'",
+ target_info->getDataLayout().getStringRepresentation().c_str());
+ LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str());
+ LLDB_LOGF(log, "Target vector alignment: %d",
+ target_info->getMaxVectorAlign());
}
m_compiler->setTarget(target_info);
@@ -508,6 +515,9 @@ ClangExpressionParser::ClangExpressionParser(
lang_opts.DoubleSquareBracketAttributes = true;
lang_opts.CPlusPlus11 = true;
+ // The Darwin libc expects this macro to be set.
+ lang_opts.GNUCVersion = 40201;
+
SetupModuleHeaderPaths(m_compiler.get(), m_include_directories,
target_sp);
}
@@ -537,8 +547,8 @@ ClangExpressionParser::ClangExpressionParser(
// Set CodeGen options
m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
m_compiler->getCodeGenOpts().InstrumentFunctions = false;
- m_compiler->getCodeGenOpts().DisableFPElim = true;
- m_compiler->getCodeGenOpts().OmitLeafFramePointer = false;
+ m_compiler->getCodeGenOpts().setFramePointer(
+ CodeGenOptions::FramePointerKind::All);
if (generate_debug_info)
m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
else
@@ -560,7 +570,9 @@ ClangExpressionParser::ClangExpressionParser(
// 6. Set up the diagnostic buffer for reporting errors
- m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter);
+ auto diag_mgr = new ClangDiagnosticManagerAdapter(
+ m_compiler->getDiagnostics().getDiagnosticOptions());
+ m_compiler->getDiagnostics().setClient(diag_mgr);
// 7. Set up the source management objects inside the compiler
m_compiler->createFileManager();
@@ -574,8 +586,8 @@ ClangExpressionParser::ClangExpressionParser(
llvm::cast<ClangPersistentVariables>(
target_sp->GetPersistentExpressionStateForLanguage(
lldb::eLanguageTypeC));
- std::unique_ptr<PPCallbacks> pp_callbacks(
- new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars));
+ std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(
+ *decl_vendor, *clang_persistent_vars, m_compiler->getSourceManager()));
m_pp_callbacks =
static_cast<LLDBPreprocessorCallbacks *>(pp_callbacks.get());
m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
@@ -592,9 +604,7 @@ ClangExpressionParser::ClangExpressionParser(
m_compiler->createASTContext();
clang::ASTContext &ast_context = m_compiler->getASTContext();
- m_ast_context.reset(
- new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str()));
- m_ast_context->setASTContext(&ast_context);
+ m_ast_context.reset(new ClangASTContext(ast_context));
std::string module_name("$__lldb_module");
@@ -872,8 +882,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
ClangDiagnosticManagerAdapter *adapter =
static_cast<ClangDiagnosticManagerAdapter *>(
m_compiler->getDiagnostics().getClient());
- clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough();
- diag_buf->FlushDiagnostics(m_compiler->getDiagnostics());
+ auto diag_buf = adapter->GetPassthrough();
adapter->ResetManager(&diagnostic_manager);
@@ -904,16 +913,19 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
}
if (temp_fd != -1) {
- lldb_private::File file(temp_fd, true);
+ lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true);
const size_t expr_text_len = strlen(expr_text);
size_t bytes_written = expr_text_len;
if (file.Write(expr_text, bytes_written).Success()) {
if (bytes_written == expr_text_len) {
file.Close();
- source_mgr.setMainFileID(source_mgr.createFileID(
- m_compiler->getFileManager().getFile(result_path),
- SourceLocation(), SrcMgr::C_User));
- created_main_file = true;
+ if (auto fileEntry =
+ m_compiler->getFileManager().getFile(result_path)) {
+ source_mgr.setMainFileID(source_mgr.createFileID(
+ *fileEntry,
+ SourceLocation(), SrcMgr::C_User));
+ created_main_file = true;
+ }
}
}
}
@@ -921,7 +933,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
if (!created_main_file) {
std::unique_ptr<MemoryBuffer> memory_buffer =
- MemoryBuffer::getMemBufferCopy(expr_text, "<lldb-expr>");
+ MemoryBuffer::getMemBufferCopy(expr_text, m_filename);
source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
}
@@ -1092,8 +1104,8 @@ bool ClangExpressionParser::RewriteExpression(
if (num_diags == 0)
return false;
- for (const Diagnostic *diag : diagnostic_manager.Diagnostics()) {
- const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
+ for (const auto &diag : diagnostic_manager.Diagnostics()) {
+ const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get());
if (diagnostic && diagnostic->HasFixIts()) {
for (const FixItHint &fixit : diagnostic->FixIts()) {
// This is cobbed from clang::Rewrite::FixItRewriter.
@@ -1181,9 +1193,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
m_expr.FunctionName());
return err;
} else {
- if (log)
- log->Printf("Found function %s for %s", function_name.AsCString(),
- m_expr.FunctionName());
+ LLDB_LOGF(log, "Found function %s for %s", function_name.AsCString(),
+ m_expr.FunctionName());
}
}
@@ -1198,9 +1209,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
LLVMUserExpression::IRPasses custom_passes;
{
auto lang = m_expr.Language();
- if (log)
- log->Printf("%s - Current expression language is %s\n", __FUNCTION__,
- Language::GetNameForLanguageType(lang));
+ LLDB_LOGF(log, "%s - Current expression language is %s\n", __FUNCTION__,
+ Language::GetNameForLanguageType(lang));
lldb::ProcessSP process_sp = exe_ctx.GetProcessSP();
if (process_sp && lang != lldb::eLanguageTypeUnknown) {
auto runtime = process_sp->GetLanguageRuntime(lang);
@@ -1210,10 +1220,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
}
if (custom_passes.EarlyPasses) {
- if (log)
- log->Printf("%s - Running Early IR Passes from LanguageRuntime on "
- "expression module '%s'",
- __FUNCTION__, m_expr.FunctionName());
+ LLDB_LOGF(log,
+ "%s - Running Early IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
custom_passes.EarlyPasses->run(*llvm_module_up);
}
@@ -1230,12 +1240,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
type_system_helper->DeclMap(); // result can be NULL
if (decl_map) {
- Stream *error_stream = nullptr;
Target *target = exe_ctx.GetTargetPtr();
- error_stream = target->GetDebugger().GetErrorFile().get();
-
+ auto &error_stream = target->GetDebugger().GetErrorStream();
IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(),
- *execution_unit_sp, *error_stream,
+ *execution_unit_sp, error_stream,
function_name.AsCString());
bool ir_can_run =
@@ -1298,9 +1306,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
process->SetDynamicCheckers(dynamic_checkers);
- if (log)
- log->Printf("== [ClangExpressionParser::PrepareForExecution] "
- "Finished installing dynamic checkers ==");
+ LLDB_LOGF(log, "== [ClangExpressionParser::PrepareForExecution] "
+ "Finished installing dynamic checkers ==");
}
if (auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>(
@@ -1316,10 +1323,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
}
if (custom_passes.LatePasses) {
- if (log)
- log->Printf("%s - Running Late IR Passes from LanguageRuntime on "
- "expression module '%s'",
- __FUNCTION__, m_expr.FunctionName());
+ LLDB_LOGF(log,
+ "%s - Running Late IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
custom_passes.LatePasses->run(*module);
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index a42c2190ffb8..79ad5728bf74 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -53,9 +53,14 @@ public:
/// @param[in] include_directories
/// List of include directories that should be used when parsing the
/// expression.
+ ///
+ /// @param[in] filename
+ /// Name of the source file that should be used when rendering
+ /// diagnostics (i.e. errors, warnings or notes from Clang).
ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr,
bool generate_debug_info,
- std::vector<ConstString> include_directories = {});
+ std::vector<std::string> include_directories = {},
+ std::string filename = "<clang expression>");
/// Destructor
~ClangExpressionParser() override;
@@ -177,7 +182,9 @@ private:
///encounters module imports
std::unique_ptr<ClangASTContext> m_ast_context;
- std::vector<ConstString> m_include_directories;
+ std::vector<std::string> m_include_directories;
+ /// File name used for the user expression.
+ std::string m_filename;
};
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index f513b1eea360..21cb33402e7f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -29,7 +29,15 @@
using namespace lldb_private;
-const char *ClangExpressionSourceCode::g_expression_prefix = R"(
+#define PREFIX_NAME "<lldb wrapper prefix>"
+
+const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME;
+
+const char *ClangExpressionSourceCode::g_expression_prefix =
+"#line 1 \"" PREFIX_NAME R"("
+#ifndef offsetof
+#define offsetof(t, d) __builtin_offsetof(t, d)
+#endif
#ifndef NULL
#define NULL (__null)
#endif
@@ -64,9 +72,6 @@ extern "C"
}
)";
-static const char *c_start_marker = " /*LLDB_BODY_START*/\n ";
-static const char *c_end_marker = ";\n /*LLDB_BODY_END*/\n";
-
namespace {
class AddMacroState {
@@ -166,6 +171,17 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit,
}
}
+lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode(
+ llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix,
+ llvm::StringRef body, Wrapping wrap)
+ : ExpressionSourceCode(name, prefix, body, wrap) {
+ // Use #line markers to pretend that we have a single-line source file
+ // containing only the user expression. This will hide our wrapper code
+ // from the user when we render diagnostics with Clang.
+ m_start_marker = "#line 1 \"" + filename.str() + "\"\n";
+ m_end_marker = "\n;\n#line 1 \"<lldb wrapper suffix>\"\n";
+}
+
namespace {
/// Allows checking if a token is contained in a given expression.
class TokenVerifier {
@@ -286,7 +302,8 @@ bool ClangExpressionSourceCode::GetText(
Target *target = exe_ctx.GetTargetPtr();
if (target) {
- if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64) {
+ if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 ||
+ target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) {
target_specific_defines = "typedef bool BOOL;\n";
}
if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64) {
@@ -398,9 +415,9 @@ bool ClangExpressionSourceCode::GetText(
case lldb::eLanguageTypeC:
case lldb::eLanguageTypeC_plus_plus:
case lldb::eLanguageTypeObjC:
- tagged_body.append(c_start_marker);
+ tagged_body.append(m_start_marker);
tagged_body.append(m_body);
- tagged_body.append(c_end_marker);
+ tagged_body.append(m_end_marker);
break;
}
switch (wrapping_language) {
@@ -474,24 +491,19 @@ bool ClangExpressionSourceCode::GetText(
bool ClangExpressionSourceCode::GetOriginalBodyBounds(
std::string transformed_text, lldb::LanguageType wrapping_language,
size_t &start_loc, size_t &end_loc) {
- const char *start_marker;
- const char *end_marker;
-
switch (wrapping_language) {
default:
return false;
case lldb::eLanguageTypeC:
case lldb::eLanguageTypeC_plus_plus:
case lldb::eLanguageTypeObjC:
- start_marker = c_start_marker;
- end_marker = c_end_marker;
break;
}
- start_loc = transformed_text.find(start_marker);
+ start_loc = transformed_text.find(m_start_marker);
if (start_loc == std::string::npos)
return false;
- start_loc += strlen(start_marker);
- end_loc = transformed_text.find(end_marker);
+ start_loc += m_start_marker.size();
+ end_loc = transformed_text.find(m_end_marker);
return end_loc != std::string::npos;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
index 894290295837..1d159670b962 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
@@ -23,15 +23,18 @@ class ExecutionContext;
class ClangExpressionSourceCode : public ExpressionSourceCode {
public:
+ /// The file name we use for the wrapper code that we inject before
+ /// the user expression.
+ static const llvm::StringRef g_prefix_file_name;
static const char *g_expression_prefix;
- static ClangExpressionSourceCode *CreateWrapped(const char *prefix,
- const char *body) {
- return new ClangExpressionSourceCode("$__lldb_expr", prefix, body, true);
+ static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename,
+ llvm::StringRef prefix,
+ llvm::StringRef body) {
+ return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body,
+ Wrap);
}
- uint32_t GetNumBodyLines();
-
/// Generates the source code that will evaluate the expression.
///
/// \param text output parameter containing the source code string.
@@ -56,14 +59,20 @@ public:
// Given a string returned by GetText, find the beginning and end of the body
// passed to CreateWrapped. Return true if the bounds could be found. This
// will also work on text with FixItHints applied.
- static bool GetOriginalBodyBounds(std::string transformed_text,
- lldb::LanguageType wrapping_language,
- size_t &start_loc, size_t &end_loc);
+ bool GetOriginalBodyBounds(std::string transformed_text,
+ lldb::LanguageType wrapping_language,
+ size_t &start_loc, size_t &end_loc);
protected:
- ClangExpressionSourceCode(const char *name, const char *prefix, const char *body,
- bool wrap) :
- ExpressionSourceCode(name, prefix, body, wrap) {}
+ ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name,
+ llvm::StringRef prefix, llvm::StringRef body,
+ Wrapping wrap);
+
+private:
+ /// String marking the start of the user expression.
+ std::string m_start_marker;
+ /// String marking the end of the user expression.
+ std::string m_end_marker;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index eabc96aa8e51..8fbfa6e47578 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -179,8 +179,7 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
m_wrapper_function_text.append(");\n}\n");
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
+ LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
// Okay, now compile this expression
diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 65c547391831..42d3f22014dd 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -30,10 +30,10 @@ static bool VerifyClangPath(const llvm::Twine &clang_path) {
if (FileSystem::Instance().IsDirectory(clang_path))
return true;
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("VerifyClangPath(): "
- "failed to stat clang resource directory at \"%s\"",
- clang_path.str().c_str());
+ LLDB_LOGF(log,
+ "VerifyClangPath(): "
+ "failed to stat clang resource directory at \"%s\"",
+ clang_path.str().c_str());
return false;
}
@@ -67,10 +67,10 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
llvm::sys::path::native(relative_path);
llvm::sys::path::append(clang_dir, relative_path);
if (!verify || VerifyClangPath(clang_dir)) {
- if (log)
- log->Printf("DefaultComputeClangResourceDir: Setting ClangResourceDir "
- "to \"%s\", verify = %s",
- clang_dir.str().str().c_str(), verify ? "true" : "false");
+ LLDB_LOGF(log,
+ "DefaultComputeClangResourceDir: Setting ClangResourceDir "
+ "to \"%s\", verify = %s",
+ clang_dir.str().str().c_str(), verify ? "true" : "false");
file_spec.GetDirectory().SetString(clang_dir);
FileSystem::Instance().Resolve(file_spec);
return true;
@@ -160,9 +160,8 @@ FileSpec lldb_private::GetClangResourceDir() {
ComputeClangResourceDirectory(lldb_file_spec, g_cached_resource_dir,
true);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("GetClangResourceDir() => '%s'",
- g_cached_resource_dir.GetPath().c_str());
+ LLDB_LOGF(log, "GetClangResourceDir() => '%s'",
+ g_cached_resource_dir.GetPath().c_str());
});
return g_cached_resource_dir;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 4a220790e50d..f3df589d7311 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -27,6 +27,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Target.h"
@@ -110,6 +111,9 @@ private:
ImportedModuleMap m_imported_modules;
ImportedModuleSet m_user_imported_modules;
const clang::ExternalASTMerger::OriginMap m_origin_map;
+ // We assume that every ASTContext has an ClangASTContext, so we also store
+ // a custom ClangASTContext for our internal ASTContext.
+ std::unique_ptr<ClangASTContext> m_ast_context;
};
} // anonymous namespace
@@ -143,7 +147,8 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
}
}
-ClangModulesDeclVendor::ClangModulesDeclVendor() {}
+ClangModulesDeclVendor::ClangModulesDeclVendor()
+ : ClangDeclVendor(eClangModuleDeclVendor) {}
ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
@@ -155,7 +160,11 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
: m_diagnostics_engine(std::move(diagnostics_engine)),
m_compiler_invocation(std::move(compiler_invocation)),
m_compiler_instance(std::move(compiler_instance)),
- m_parser(std::move(parser)), m_origin_map() {}
+ m_parser(std::move(parser)), m_origin_map() {
+
+ // Initialize our ClangASTContext.
+ m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext()));
+}
void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
std::set<ClangModulesDeclVendor::ModuleID> &exports,
@@ -237,11 +246,11 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
bool is_system = true;
bool is_framework = false;
- auto *dir =
+ auto dir =
HS.getFileMgr().getDirectory(module.search_path.GetStringRef());
if (!dir)
return error();
- auto *file = HS.lookupModuleMapFile(dir, is_framework);
+ auto *file = HS.lookupModuleMapFile(*dir, is_framework);
if (!file)
return error();
if (!HS.loadModuleMapFile(file, is_system))
@@ -562,8 +571,9 @@ ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
clang::ExternalASTMerger::ImporterSource
ClangModulesDeclVendorImpl::GetImporterSource() {
- return {m_compiler_instance->getASTContext(),
- m_compiler_instance->getFileManager(), m_origin_map};
+ return clang::ExternalASTMerger::ImporterSource(
+ m_compiler_instance->getASTContext(),
+ m_compiler_instance->getFileManager(), m_origin_map);
}
static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index d5c8757bdcd0..e099b59041d8 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -10,22 +10,27 @@
#define liblldb_ClangModulesDeclVendor_h
#include "lldb/Core/ClangForward.h"
-#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Platform.h"
+#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
+
#include <set>
#include <vector>
namespace lldb_private {
-class ClangModulesDeclVendor : public DeclVendor {
+class ClangModulesDeclVendor : public ClangDeclVendor {
public:
// Constructors and Destructors
ClangModulesDeclVendor();
~ClangModulesDeclVendor() override;
+ static bool classof(const DeclVendor *vendor) {
+ return vendor->GetKind() == eClangModuleDeclVendor;
+ }
+
static ClangModulesDeclVendor *Create(Target &target);
typedef std::vector<ConstString> ModulePath;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 742a14992dc9..24dd705e37b1 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -23,8 +23,7 @@ using namespace lldb;
using namespace lldb_private;
ClangPersistentVariables::ClangPersistentVariables()
- : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
- m_next_persistent_variable_id(0) {}
+ : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang) {}
ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
const lldb::ValueObjectSP &valobj_sp) {
@@ -43,13 +42,25 @@ void ClangPersistentVariables::RemovePersistentVariable(
lldb::ExpressionVariableSP variable) {
RemoveVariable(variable);
- const char *name = variable->GetName().AsCString();
+ // Check if the removed variable was the last one that was created. If yes,
+ // reuse the variable id for the next variable.
- if (*name != '$')
+ // Nothing to do if we have not assigned a variable id so far.
+ if (m_next_persistent_variable_id == 0)
return;
- name++;
- if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
+ llvm::StringRef name = variable->GetName().GetStringRef();
+ // Remove the prefix from the variable that only the indes is left.
+ if (!name.consume_front(GetPersistentVariablePrefix(false)))
+ return;
+
+ // Check if the variable contained a variable id.
+ uint32_t variable_id;
+ if (name.getAsInteger(10, variable_id))
+ return;
+ // If it's the most recent variable id that was assigned, make sure that this
+ // variable id will be used for the next persistent variable.
+ if (variable_id == m_next_persistent_variable_id - 1)
m_next_persistent_variable_id--;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index b39f89ad7eef..95e6c3ac963d 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -45,11 +45,20 @@ public:
uint32_t addr_byte_size) override;
void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
- llvm::StringRef
- GetPersistentVariablePrefix(bool is_error) const override {
+
+ llvm::StringRef GetPersistentVariablePrefix(bool is_error) const override {
return "$";
}
+ /// Returns the next file name that should be used for user expressions.
+ std::string GetNextExprFileName() {
+ std::string name;
+ name.append("<user expression ");
+ name.append(std::to_string(m_next_user_file_id++));
+ name.append(">");
+ return name;
+ }
+
llvm::Optional<CompilerType>
GetCompilerTypeFromPersistentDecl(ConstString type_name) override;
@@ -66,8 +75,10 @@ public:
}
private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by
- ///GetNextResultName().
+ /// The counter used by GetNextExprFileName.
+ uint32_t m_next_user_file_id = 0;
+ // The counter used by GetNextPersistentVariableName
+ uint32_t m_next_persistent_variable_id = 0;
typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap;
PersistentDeclMap
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 2dae5b7022f3..da1ca785635c 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
+
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -21,9 +23,9 @@
#include "ClangDiagnostic.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
-#include "ClangExpressionSourceCode.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
+#include "CppModuleConfiguration.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -90,21 +92,18 @@ ClangUserExpression::~ClangUserExpression() {}
void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("ClangUserExpression::ScanContext()");
+ LLDB_LOGF(log, "ClangUserExpression::ScanContext()");
m_target = exe_ctx.GetTargetPtr();
if (!(m_allow_cxx || m_allow_objc)) {
- if (log)
- log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
+ LLDB_LOGF(log, " [CUE::SC] Settings inhibit C++ and Objective-C");
return;
}
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == nullptr) {
- if (log)
- log->Printf(" [CUE::SC] Null stack frame");
+ LLDB_LOGF(log, " [CUE::SC] Null stack frame");
return;
}
@@ -112,8 +111,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
lldb::eSymbolContextBlock);
if (!sym_ctx.function) {
- if (log)
- log->Printf(" [CUE::SC] Null function");
+ LLDB_LOGF(log, " [CUE::SC] Null function");
return;
}
@@ -121,16 +119,14 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
Block *function_block = sym_ctx.GetFunctionBlock();
if (!function_block) {
- if (log)
- log->Printf(" [CUE::SC] Null function block");
+ LLDB_LOGF(log, " [CUE::SC] Null function block");
return;
}
CompilerDeclContext decl_context = function_block->GetDeclContext();
if (!decl_context) {
- if (log)
- log->Printf(" [CUE::SC] Null decl context");
+ LLDB_LOGF(log, " [CUE::SC] Null decl context");
return;
}
@@ -317,17 +313,13 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
// count is not available, [myArray count] returns id, which can't be directly
// cast to int without causing a clang error.
static void ApplyObjcCastHack(std::string &expr) {
-#define OBJC_CAST_HACK_FROM "(int)["
-#define OBJC_CAST_HACK_TO "(int)(long long)["
-
- size_t from_offset;
+ const std::string from = "(int)[";
+ const std::string to = "(int)(long long)[";
- while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
- expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1,
- OBJC_CAST_HACK_TO);
+ size_t offset;
-#undef OBJC_CAST_HACK_TO
-#undef OBJC_CAST_HACK_FROM
+ while ((offset = expr.find(from)) != expr.npos)
+ expr.replace(offset, from.size(), to);
}
bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager,
@@ -336,6 +328,7 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man
if (PersistentExpressionState *persistent_state =
target->GetPersistentExpressionStateForLanguage(
lldb::eLanguageTypeC)) {
+ m_clang_state = llvm::cast<ClangPersistentVariables>(persistent_state);
m_result_delegate.RegisterPersistentState(persistent_state);
} else {
diagnostic_manager.PutString(
@@ -384,30 +377,34 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
}
}
-void ClangUserExpression::UpdateLanguageForExpr(
+void ClangUserExpression::UpdateLanguageForExpr() {
+ m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
+ return;
+ if (m_in_cplusplus_method)
+ m_expr_lang = lldb::eLanguageTypeC_plus_plus;
+ else if (m_in_objectivec_method)
+ m_expr_lang = lldb::eLanguageTypeObjC;
+ else
+ m_expr_lang = lldb::eLanguageTypeC;
+}
+
+void ClangUserExpression::CreateSourceCode(
DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
std::vector<std::string> modules_to_import, bool for_completion) {
- m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
+ m_filename = m_clang_state->GetNextExprFileName();
std::string prefix = m_expr_prefix;
if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
m_transformed_text = m_expr_text;
} else {
- std::unique_ptr<ClangExpressionSourceCode> source_code(
- ClangExpressionSourceCode::CreateWrapped(prefix.c_str(),
- m_expr_text.c_str()));
-
- if (m_in_cplusplus_method)
- m_expr_lang = lldb::eLanguageTypeC_plus_plus;
- else if (m_in_objectivec_method)
- m_expr_lang = lldb::eLanguageTypeObjC;
- else
- m_expr_lang = lldb::eLanguageTypeC;
-
- if (!source_code->GetText(m_transformed_text, m_expr_lang,
- m_in_static_method, exe_ctx, !m_ctx_obj,
- for_completion, modules_to_import)) {
+ m_source_code.reset(ClangExpressionSourceCode::CreateWrapped(
+ m_filename, prefix.c_str(), m_expr_text.c_str()));
+
+ if (!m_source_code->GetText(m_transformed_text, m_expr_lang,
+ m_in_static_method, exe_ctx, !m_ctx_obj,
+ for_completion, modules_to_import)) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
"couldn't construct expression body");
return;
@@ -417,7 +414,7 @@ void ClangUserExpression::UpdateLanguageForExpr(
// transformed code. We need this later for the code completion.
std::size_t original_start;
std::size_t original_end;
- bool found_bounds = source_code->GetOriginalBodyBounds(
+ bool found_bounds = m_source_code->GetOriginalBodyBounds(
m_transformed_text, m_expr_lang, original_start, original_end);
if (found_bounds)
m_user_expression_start_pos = original_start;
@@ -437,48 +434,70 @@ static bool SupportsCxxModuleImport(lldb::LanguageType language) {
}
}
-std::vector<std::string>
-ClangUserExpression::GetModulesToImport(ExecutionContext &exe_ctx) {
+/// Utility method that puts a message into the expression log and
+/// returns an invalid module configuration.
+static CppModuleConfiguration LogConfigError(const std::string &msg) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ LLDB_LOG(log, "[C++ module config] {0}", msg);
+ return CppModuleConfiguration();
+}
- if (!SupportsCxxModuleImport(Language()))
- return {};
+CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
+ ExecutionContext &exe_ctx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ // Don't do anything if this is not a C++ module configuration.
+ if (!SupportsCxxModuleImport(language))
+ return LogConfigError("Language doesn't support C++ modules");
Target *target = exe_ctx.GetTargetPtr();
- if (!target || !target->GetEnableImportStdModule())
- return {};
+ if (!target)
+ return LogConfigError("No target");
+
+ if (!target->GetEnableImportStdModule())
+ return LogConfigError("Importing std module not enabled in settings");
StackFrame *frame = exe_ctx.GetFramePtr();
if (!frame)
- return {};
+ return LogConfigError("No frame");
Block *block = frame->GetFrameBlock();
if (!block)
- return {};
+ return LogConfigError("No block");
SymbolContext sc;
block->CalculateSymbolContext(&sc);
if (!sc.comp_unit)
- return {};
-
- if (log) {
- for (const SourceModule &m : sc.comp_unit->GetImportedModules()) {
- LLDB_LOG(log, "Found module in compile unit: {0:$[.]} - include dir: {1}",
- llvm::make_range(m.path.begin(), m.path.end()), m.search_path);
+ return LogConfigError("Couldn't calculate symbol context");
+
+ // Build a list of files we need to analyze to build the configuration.
+ FileSpecList files;
+ for (const FileSpec &f : sc.comp_unit->GetSupportFiles())
+ files.AppendIfUnique(f);
+ // We also need to look at external modules in the case of -gmodules as they
+ // contain the support files for libc++ and the C library.
+ sc.comp_unit->ForEachExternalModule([&files](lldb::ModuleSP module) {
+ for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) {
+ const FileSpecList &support_files =
+ module->GetCompileUnitAtIndex(i)->GetSupportFiles();
+ for (const FileSpec &f : support_files) {
+ files.AppendIfUnique(f);
+ }
}
+ });
+
+ LLDB_LOG(log, "[C++ module config] Found {0} support files to analyze",
+ files.GetSize());
+ if (log && log->GetVerbose()) {
+ for (const FileSpec &f : files)
+ LLDB_LOGV(log, "[C++ module config] Analyzing support file: {0}",
+ f.GetPath());
}
- for (const SourceModule &m : sc.comp_unit->GetImportedModules())
- m_include_directories.push_back(m.search_path);
-
- // Check if we imported 'std' or any of its submodules.
- // We currently don't support importing any other modules in the expression
- // parser.
- for (const SourceModule &m : sc.comp_unit->GetImportedModules())
- if (!m.path.empty() && m.path.front() == "std")
- return {"std"};
-
- return {};
+ // Try to create a configuration from the files. If there is no valid
+ // configuration possible with the files, this just returns an invalid
+ // configuration.
+ return CppModuleConfiguration(files);
}
bool ClangUserExpression::PrepareForParsing(
@@ -506,14 +525,21 @@ bool ClangUserExpression::PrepareForParsing(
SetupDeclVendor(exe_ctx, m_target);
- std::vector<std::string> used_modules = GetModulesToImport(exe_ctx);
- m_imported_cpp_modules = !used_modules.empty();
+ CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx);
+ llvm::ArrayRef<std::string> imported_modules =
+ module_config.GetImportedModules();
+ m_imported_cpp_modules = !imported_modules.empty();
+ m_include_directories = module_config.GetIncludeDirs();
LLDB_LOG(log, "List of imported modules in expression: {0}",
- llvm::make_range(used_modules.begin(), used_modules.end()));
-
- UpdateLanguageForExpr(diagnostic_manager, exe_ctx, used_modules,
- for_completion);
+ llvm::make_range(imported_modules.begin(), imported_modules.end()));
+ LLDB_LOG(log, "List of include directories gathered for modules: {0}",
+ llvm::make_range(m_include_directories.begin(),
+ m_include_directories.end()));
+
+ UpdateLanguageForExpr();
+ CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules,
+ for_completion);
return true;
}
@@ -527,8 +553,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false))
return false;
- if (log)
- log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
+ LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
////////////////////////////////////
// Set up the target and compiler
@@ -573,7 +598,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
// parser_sp will never be empty.
ClangExpressionParser parser(exe_scope, *this, generate_debug_info,
- m_include_directories);
+ m_include_directories, m_filename);
unsigned num_errors = parser.Parse(diagnostic_manager);
@@ -586,8 +611,11 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
size_t fixed_end;
const std::string &fixed_expression =
diagnostic_manager.GetFixedExpression();
- if (ClangExpressionSourceCode::GetOriginalBodyBounds(
- fixed_expression, m_expr_lang, fixed_start, fixed_end))
+ // Retrieve the original expression in case we don't have a top level
+ // expression (which has no surrounding source code).
+ if (m_source_code &&
+ m_source_code->GetOriginalBodyBounds(fixed_expression, m_expr_lang,
+ fixed_start, fixed_end))
m_fixed_text =
fixed_expression.substr(fixed_start, fixed_end - fixed_start);
}
@@ -648,12 +676,10 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
register_execution_unit = true;
}
- if (register_execution_unit) {
- llvm::cast<PersistentExpressionState>(
- exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
- m_language))
+ if (register_execution_unit)
+ exe_ctx.GetTargetPtr()
+ ->GetPersistentExpressionStateForLanguage(m_language)
->RegisterExecutionUnit(m_execution_unit_sp);
- }
}
if (generate_debug_info) {
@@ -726,8 +752,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ true))
return false;
- if (log)
- log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
+ LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
//////////////////////////
// Parse the expression
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 24c152bdb45d..d94f9cc5e066 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -15,6 +15,7 @@
#include "ASTStructExtractor.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionHelper.h"
+#include "ClangExpressionSourceCode.h"
#include "ClangExpressionVariable.h"
#include "IRForTarget.h"
@@ -105,6 +106,9 @@ public:
/// If not eResultTypeAny, the type to use for the expression
/// result.
///
+ /// \param[in] options
+ /// Additional options for the expression.
+ ///
/// \param[in] ctx_obj
/// The object (if any) in which context the expression
/// must be evaluated. For details see the comment to
@@ -175,11 +179,11 @@ private:
lldb::addr_t struct_address,
DiagnosticManager &diagnostic_manager) override;
- std::vector<std::string> GetModulesToImport(ExecutionContext &exe_ctx);
- void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager,
- ExecutionContext &exe_ctx,
- std::vector<std::string> modules_to_import,
- bool for_completion);
+ void CreateSourceCode(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ std::vector<std::string> modules_to_import,
+ bool for_completion);
+ void UpdateLanguageForExpr();
bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
ExecutionContext &exe_ctx);
bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
@@ -205,13 +209,17 @@ private:
/// The language type of the current expression.
lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown;
/// The include directories that should be used when parsing the expression.
- std::vector<ConstString> m_include_directories;
+ std::vector<std::string> m_include_directories;
/// The absolute character position in the transformed source code where the
/// user code (as typed by the user) starts. If the variable is empty, then we
/// were not able to calculate this position.
llvm::Optional<size_t> m_user_expression_start_pos;
ResultDelegate m_result_delegate;
+ ClangPersistentVariables *m_clang_state;
+ std::unique_ptr<ClangExpressionSourceCode> m_source_code;
+ /// File name used for the expression.
+ std::string m_filename;
/// The object (if any) in which context the expression is evaluated.
/// See the comment to `UserExpression::Evaluate` for details.
@@ -219,6 +227,23 @@ private:
/// True iff this expression explicitly imported C++ modules.
bool m_imported_cpp_modules = false;
+
+ /// True if the expression parser should enforce the presence of a valid class
+ /// pointer in order to generate the expression as a method.
+ bool m_enforce_valid_object = true;
+ /// True if the expression is compiled as a C++ member function (true if it
+ /// was parsed when exe_ctx was in a C++ method).
+ bool m_in_cplusplus_method = false;
+ /// True if the expression is compiled as an Objective-C method (true if it
+ /// was parsed when exe_ctx was in an Objective-C method).
+ bool m_in_objectivec_method = false;
+ /// True if the expression is compiled as a static (or class) method
+ /// (currently true if it was parsed when exe_ctx was in an Objective-C class
+ /// method).
+ bool m_in_static_method = false;
+ /// True if "this" or "self" must be looked up and passed in. False if the
+ /// expression doesn't really use them and they can be NULL.
+ bool m_needs_object_ptr = false;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 5eec224477fc..564c62c6a2c6 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
+
#include "ClangUtilityFunction.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
new file mode 100644
index 000000000000..51ae73285b53
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -0,0 +1,82 @@
+//===-- CppModuleConfiguration.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 "CppModuleConfiguration.h"
+
+#include "ClangHost.h"
+#include "lldb/Host/FileSystem.h"
+
+using namespace lldb_private;
+
+bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) {
+ // Setting for the first time always works.
+ if (m_first) {
+ m_path = path.str();
+ m_valid = true;
+ m_first = false;
+ return true;
+ }
+ // Changing the path to the same value is fine.
+ if (m_path == path)
+ return true;
+
+ // Changing the path after it was already set is not allowed.
+ m_valid = false;
+ return false;
+}
+
+bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
+ using namespace llvm::sys::path;
+ // Convert to slashes to make following operations simpler.
+ std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef());
+ llvm::StringRef posix_dir(dir_buffer);
+
+ // Check for /c++/vX/ that is used by libc++.
+ static llvm::Regex libcpp_regex(R"regex(/c[+][+]/v[0-9]/)regex");
+ if (libcpp_regex.match(f.GetPath())) {
+ // Strip away libc++'s /experimental directory if there is one.
+ posix_dir.consume_back("/experimental");
+ return m_std_inc.TrySet(posix_dir);
+ }
+
+ // Check for /usr/include. On Linux this might be /usr/include/bits, so
+ // we should remove that '/bits' suffix to get the actual include directory.
+ if (posix_dir.endswith("/usr/include/bits"))
+ posix_dir.consume_back("/bits");
+ if (posix_dir.endswith("/usr/include"))
+ return m_c_inc.TrySet(posix_dir);
+
+ // File wasn't interesting, continue analyzing.
+ return true;
+}
+
+bool CppModuleConfiguration::hasValidConfig() {
+ // We all these include directories to have a valid usable configuration.
+ return m_c_inc.Valid() && m_std_inc.Valid();
+}
+
+CppModuleConfiguration::CppModuleConfiguration(
+ const FileSpecList &support_files) {
+ // Analyze all files we were given to build the configuration.
+ bool error = !llvm::all_of(support_files,
+ std::bind(&CppModuleConfiguration::analyzeFile,
+ this, std::placeholders::_1));
+ // If we have a valid configuration at this point, set the
+ // include directories and module list that should be used.
+ if (!error && hasValidConfig()) {
+ // Calculate the resource directory for LLDB.
+ llvm::SmallString<256> resource_dir;
+ llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(),
+ "include");
+ m_resource_inc = resource_dir.str();
+
+ // This order matches the way Clang orders these directories.
+ m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()};
+ m_imported_modules = {"std"};
+ }
+}
diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
new file mode 100644
index 000000000000..8e892e37d0de
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -0,0 +1,84 @@
+//===-- CppModuleConfiguration.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_CppModuleConfiguration_h_
+#define liblldb_CppModuleConfiguration_h_
+
+#include <lldb/Core/FileSpecList.h>
+#include <llvm/Support/Regex.h>
+
+namespace lldb_private {
+
+/// A Clang configuration when importing C++ modules.
+///
+/// Includes a list of include paths that should be used when importing
+/// and a list of modules that can be imported. Currently only used when
+/// importing the 'std' module and its dependencies.
+class CppModuleConfiguration {
+ /// Utility class for a path that can only be set once.
+ class SetOncePath {
+ std::string m_path;
+ bool m_valid = false;
+ /// True iff this path hasn't been set yet.
+ bool m_first = true;
+
+ public:
+ /// Try setting the path. Returns true if the path was set and false if
+ /// the path was already set.
+ LLVM_NODISCARD bool TrySet(llvm::StringRef path);
+ /// Return the path if there is one.
+ std::string Get() const {
+ assert(m_valid && "Called Get() on an invalid SetOncePath?");
+ return m_path;
+ }
+ /// Returns true iff this path was set exactly once so far.
+ bool Valid() const { return m_valid; }
+ };
+
+ /// If valid, the include path used for the std module.
+ SetOncePath m_std_inc;
+ /// If valid, the include path to the C library (e.g. /usr/include).
+ SetOncePath m_c_inc;
+ /// The Clang resource include path for this configuration.
+ std::string m_resource_inc;
+
+ std::vector<std::string> m_include_dirs;
+ std::vector<std::string> m_imported_modules;
+
+ /// Analyze a given source file to build the current configuration.
+ /// Returns false iff there was a fatal error that makes analyzing any
+ /// further files pointless as the configuration is now invalid.
+ bool analyzeFile(const FileSpec &f);
+
+public:
+ /// Creates a configuraiton by analyzing the given list of used source files.
+ ///
+ /// Currently only looks at the used paths and doesn't actually access the
+ /// files on the disk.
+ explicit CppModuleConfiguration(const FileSpecList &support_files);
+ /// Creates an empty and invalid configuration.
+ CppModuleConfiguration() {}
+
+ /// Returns true iff this is a valid configuration that can be used to
+ /// load and compile modules.
+ bool hasValidConfig();
+
+ /// Returns a list of include directories that should be used when using this
+ /// configuration (e.g. {"/usr/include", "/usr/include/c++/v1"}).
+ llvm::ArrayRef<std::string> GetIncludeDirs() const { return m_include_dirs; }
+
+ /// Returns a list of (top level) modules that should be imported when using
+ /// this configuration (e.g. {"std"}).
+ llvm::ArrayRef<std::string> GetImportedModules() const {
+ return m_imported_modules;
+ }
+};
+
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index f8e004fe7d4a..d5ffb9529f36 100644
--- a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -320,9 +320,8 @@ protected:
bool InstrumentInstruction(llvm::Instruction *inst) override {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Instrumenting load/store instruction: %s\n",
- PrintValue(inst).c_str());
+ LLDB_LOGF(log, "Instrumenting load/store instruction: %s\n",
+ PrintValue(inst).c_str());
if (!m_valid_pointer_check_func)
m_valid_pointer_check_func =
@@ -483,9 +482,8 @@ protected:
std::string name_str = called_function->getName().str();
const char *name_cstr = name_str.c_str();
- if (log)
- log->Printf("Found call to %s: %s\n", name_cstr,
- PrintValue(call_inst).c_str());
+ LLDB_LOGF(log, "Found call to %s: %s\n", name_cstr,
+ PrintValue(call_inst).c_str());
if (name_str.find("objc_msgSend") == std::string::npos)
return true;
@@ -520,10 +518,9 @@ protected:
return true;
}
- if (log)
- log->Printf(
- "Function name '%s' contains 'objc_msgSend' but is not handled",
- name_str.c_str());
+ LLDB_LOGF(log,
+ "Function name '%s' contains 'objc_msgSend' but is not handled",
+ name_str.c_str());
return true;
}
@@ -548,8 +545,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) {
llvm::Function *function = M.getFunction(StringRef(m_func_name));
if (!function) {
- if (log)
- log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
+ LLDB_LOGF(log, "Couldn't find %s() in the module", m_func_name.c_str());
return false;
}
@@ -582,7 +578,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) {
oss.flush();
- log->Printf("Module after dynamic checks: \n%s", s.c_str());
+ LLDB_LOGF(log, "Module after dynamic checks: \n%s", s.c_str());
}
return true;
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 07acb2e1030f..4e871f7d6a44 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -43,6 +43,8 @@ using namespace llvm;
static char ID;
+typedef SmallVector<Instruction *, 2> InstrList;
+
IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
: m_maker(maker), m_values() {}
@@ -153,6 +155,15 @@ clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
return DeclForGlobal(global_val, m_module);
}
+/// 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
+ if (check_ms_abi)
+ result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI
+ return result;
+}
+
bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -164,64 +175,58 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- std::string result_name_str;
- const char *result_name = nullptr;
+ llvm::StringRef result_name;
+ bool found_result = false;
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
- ve = value_symbol_table.end();
- vi != ve; ++vi) {
- result_name_str = vi->first().str();
- const char *value_name = result_name_str.c_str();
+ for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
+ result_name = value_symbol.first();
- if (strstr(value_name, "$__lldb_expr_result_ptr") &&
- strncmp(value_name, "_ZGV", 4)) {
- result_name = value_name;
+ // Check if this is a guard variable. It seems this causes some hiccups
+ // on Windows, so let's only check for Itanium guard variables.
+ bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);
+
+ if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {
+ found_result = true;
m_result_is_pointer = true;
break;
}
- if (strstr(value_name, "$__lldb_expr_result") &&
- strncmp(value_name, "_ZGV", 4)) {
- result_name = value_name;
+ if (result_name.contains("$__lldb_expr_result") && !is_guard_var) {
+ found_result = true;
m_result_is_pointer = false;
break;
}
}
- if (!result_name) {
- if (log)
- log->PutCString("Couldn't find result variable");
+ if (!found_result) {
+ LLDB_LOG(log, "Couldn't find result variable");
return true;
}
- if (log)
- log->Printf("Result name: \"%s\"", result_name);
+ LLDB_LOG(log, "Result name: \"{0}\"", result_name);
Value *result_value = m_module->getNamedValue(result_name);
if (!result_value) {
- if (log)
- log->PutCString("Result variable had no data");
+ LLDB_LOG(log, "Result variable had no data");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
- "name (%s) exists, but not its definition\n",
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
+ "name ({0}) exists, but not its definition\n",
result_name);
return false;
}
- if (log)
- log->Printf("Found result in the IR: \"%s\"",
- PrintValue(result_value, false).c_str());
+ LLDB_LOG(log, "Found result in the IR: \"{0}\"",
+ PrintValue(result_value, false));
GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
if (!result_global) {
- if (log)
- log->PutCString("Result variable isn't a GlobalVariable");
+ LLDB_LOG(log, "Result variable isn't a GlobalVariable");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
"is defined, but is not a global variable\n",
result_name);
@@ -230,10 +235,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
clang::NamedDecl *result_decl = DeclForGlobal(result_global);
if (!result_decl) {
- if (log)
- log->PutCString("Result variable doesn't have a corresponding Decl");
+ LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
"does not have a corresponding Clang entity\n",
result_name);
@@ -246,16 +250,15 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
result_decl->print(decl_desc_stream);
decl_desc_stream.flush();
- log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
+ LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
}
clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
if (!result_var) {
- if (log)
- log->PutCString("Result variable Decl isn't a VarDecl");
+ LLDB_LOG(log, "Result variable Decl isn't a VarDecl");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
- "(%s)'s corresponding Clang entity isn't a "
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable "
+ "({0})'s corresponding Clang entity isn't a "
"variable\n",
result_name);
@@ -292,10 +295,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::ClangASTContext::GetASTContext(
&result_decl->getASTContext()));
} else {
- if (log)
- log->PutCString("Expected result to have pointer type, but it did not");
+ LLDB_LOG(log, "Expected result to have pointer type, but it did not");
- m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
+ m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
"is not a pointer variable\n",
result_name);
@@ -316,8 +318,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
- if (log)
- log->Printf("Result type has unknown size");
+ LLDB_LOG(log, "Result type has unknown size");
m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
"couldn't be determined\n",
@@ -329,15 +330,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
- log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
+ LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
}
m_result_name = lldb_private::ConstString("$RESULT_NAME");
- if (log)
- log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
- m_result_name.GetCString(),
- m_result_type.GetByteSize(nullptr).getValueOr(0));
+ LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
+ m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0));
// Construct a new result global and set up its metadata
@@ -369,10 +368,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
m_module->getNamedMetadata("clang.global.decl.ptrs");
named_metadata->addOperand(persistent_global_md);
- if (log)
- log->Printf("Replacing \"%s\" with \"%s\"",
- PrintValue(result_global).c_str(),
- PrintValue(new_result_global).c_str());
+ LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),
+ PrintValue(new_result_global));
if (result_global->use_empty()) {
// We need to synthesize a store for this variable, because otherwise
@@ -385,11 +382,10 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
return false;
if (!result_global->hasInitializer()) {
- if (log)
- log->Printf("Couldn't find initializer for unused variable");
+ LLDB_LOG(log, "Couldn't find initializer for unused variable");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
- "(%s) has no writes and no initializer\n",
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable "
+ "({0}) has no writes and no initializer\n",
result_name);
return false;
@@ -400,9 +396,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
StoreInst *synthesized_store =
new StoreInst(initializer, new_result_global, first_entry_instruction);
- if (log)
- log->Printf("Synthesized result store \"%s\"\n",
- PrintValue(synthesized_store).c_str());
+ LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
+ PrintValue(synthesized_store));
} else {
result_global->replaceAllUsesWith(new_result_global);
}
@@ -438,7 +433,6 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
missing_weak);
if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
- if (log)
log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
@@ -448,9 +442,8 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
return false;
}
- if (log)
- log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
- CFStringCreateWithBytes_addr);
+ LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
+ CFStringCreateWithBytes_addr);
// Build the function type:
//
@@ -543,9 +536,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
m_error_stream)) {
- if (log)
- log->PutCString(
- "Couldn't replace the NSString with the result of the call");
+ LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");
m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
"Objective-C constant string with a dynamic "
@@ -565,21 +556,17 @@ bool IRForTarget::RewriteObjCConstStrings() {
ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
- ve = value_symbol_table.end();
- vi != ve; ++vi) {
- std::string value_name = vi->first().str();
- const char *value_name_cstr = value_name.c_str();
+ for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
+ llvm::StringRef value_name = value_symbol.first();
- if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
- Value *nsstring_value = vi->second;
+ if (value_name.contains("_unnamed_cfstring_")) {
+ Value *nsstring_value = value_symbol.second;
GlobalVariable *nsstring_global =
dyn_cast<GlobalVariable>(nsstring_value);
if (!nsstring_global) {
- if (log)
- log->PutCString("NSString variable is not a GlobalVariable");
+ LLDB_LOG(log, "NSString variable is not a GlobalVariable");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string is not a global variable\n");
@@ -588,8 +575,7 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
if (!nsstring_global->hasInitializer()) {
- if (log)
- log->PutCString("NSString variable does not have an initializer");
+ LLDB_LOG(log, "NSString variable does not have an initializer");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string does not have an initializer\n");
@@ -601,9 +587,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
if (!nsstring_struct) {
- if (log)
- log->PutCString(
- "NSString variable's initializer is not a ConstantStruct");
+ LLDB_LOG(log,
+ "NSString variable's initializer is not a ConstantStruct");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string is not a structure constant\n");
@@ -621,10 +606,11 @@ bool IRForTarget::RewriteObjCConstStrings() {
// };
if (nsstring_struct->getNumOperands() != 4) {
- if (log)
- log->Printf("NSString variable's initializer structure has an "
- "unexpected number of members. Should be 4, is %d",
- nsstring_struct->getNumOperands());
+
+ LLDB_LOG(log,
+ "NSString variable's initializer structure has an "
+ "unexpected number of members. Should be 4, is {0}",
+ nsstring_struct->getNumOperands());
m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
"Objective-C constant string is not as "
@@ -636,8 +622,7 @@ bool IRForTarget::RewriteObjCConstStrings() {
Constant *nsstring_member = nsstring_struct->getOperand(2);
if (!nsstring_member) {
- if (log)
- log->PutCString("NSString initializer's str element was empty");
+ LLDB_LOG(log, "NSString initializer's str element was empty");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string does not have a string "
@@ -649,9 +634,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
if (!nsstring_expr) {
- if (log)
- log->PutCString(
- "NSString initializer's str element is not a ConstantExpr");
+ LLDB_LOG(log,
+ "NSString initializer's str element is not a ConstantExpr");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string's string initializer is not "
@@ -671,9 +655,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
if (!cstr_global) {
- if (log)
- log->PutCString(
- "NSString initializer's str element is not a GlobalVariable");
+ LLDB_LOG(log,
+ "NSString initializer's str element is not a GlobalVariable");
m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
"constant string initializer\n");
@@ -682,9 +665,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
if (!cstr_global->hasInitializer()) {
- if (log)
- log->PutCString("NSString initializer's str element does not have an "
- "initializer");
+ LLDB_LOG(log, "NSString initializer's str element does not have an "
+ "initializer");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string's string initializer doesn't "
@@ -726,21 +708,18 @@ bool IRForTarget::RewriteObjCConstStrings() {
ConstantDataArray *cstr_array =
dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
- if (log) {
- if (cstr_array)
- log->Printf("Found NSString constant %s, which contains \"%s\"",
- value_name_cstr, cstr_array->getAsString().str().c_str());
- else
- log->Printf("Found NSString constant %s, which contains \"\"",
- value_name_cstr);
- }
+ if (cstr_array)
+ LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",
+ value_name, cstr_array->getAsString());
+ else
+ LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",
+ value_name);
if (!cstr_array)
cstr_global = nullptr;
if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
- if (log)
- log->PutCString("Error rewriting the constant string");
+ LLDB_LOG(log, "Error rewriting the constant string");
// We don't print an error message here because RewriteObjCConstString
// has done so for us.
@@ -750,19 +729,15 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
}
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
- ve = value_symbol_table.end();
- vi != ve; ++vi) {
- std::string value_name = vi->first().str();
- const char *value_name_cstr = value_name.c_str();
+ for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
+ llvm::StringRef value_name = value_symbol.first();
- if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
- GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
+ if (value_name == "__CFConstantStringClassReference") {
+ GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
if (!gv) {
- if (log)
- log->PutCString(
- "__CFConstantStringClassReference is not a global variable");
+ LLDB_LOG(log,
+ "__CFConstantStringClassReference is not a global variable");
m_error_stream.Printf("Internal error [IRForTarget]: Found a "
"CFConstantStringClassReference, but it is not a "
@@ -850,9 +825,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
std::string omvn_initializer_string = omvn_initializer_array->getAsString();
- if (log)
- log->Printf("Found Objective-C selector reference \"%s\"",
- omvn_initializer_string.c_str());
+ LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
+ omvn_initializer_string);
// Construct a call to sel_registerName
@@ -866,9 +840,7 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
return false;
- if (log)
- log->Printf("Found sel_registerName at 0x%" PRIx64,
- sel_registerName_addr);
+ LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);
// Build the function type: struct objc_selector
// *sel_registerName(uint8_t*)
@@ -921,32 +893,21 @@ bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
-
InstrList selector_loads;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
-
+ for (Instruction &inst : basic_block) {
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (IsObjCSelectorRef(load->getPointerOperand()))
selector_loads.push_back(&inst);
}
- InstrIterator iter;
-
- for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
- if (!RewriteObjCSelector(*iter)) {
+ for (Instruction *inst : selector_loads) {
+ if (!RewriteObjCSelector(inst)) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
"static reference to an Objective-C selector to a "
"dynamic reference\n");
- if (log)
- log->PutCString(
- "Couldn't rewrite a reference to an Objective-C selector");
+ LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");
return false;
}
@@ -1022,9 +983,8 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
std::string ocn_initializer_string = ocn_initializer_array->getAsString();
- if (log)
- log->Printf("Found Objective-C class reference \"%s\"",
- ocn_initializer_string.c_str());
+ LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
+ ocn_initializer_string);
// Construct a call to objc_getClass
@@ -1038,9 +998,7 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
return false;
- if (log)
- log->Printf("Found objc_getClass at 0x%" PRIx64,
- objc_getClass_addr);
+ LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr);
// Build the function type: %struct._objc_class *objc_getClass(i8*)
@@ -1086,32 +1044,21 @@ bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
-
InstrList class_loads;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
-
+ for (Instruction &inst : basic_block) {
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (IsObjCClassReference(load->getPointerOperand()))
class_loads.push_back(&inst);
}
- InstrIterator iter;
-
- for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) {
- if (!RewriteObjCClassReference(*iter)) {
+ for (Instruction *inst : class_loads) {
+ if (!RewriteObjCClassReference(inst)) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
"static reference to an Objective-C class to a "
"dynamic reference\n");
- if (log)
- log->PutCString(
- "Couldn't rewrite a reference to an Objective-C class");
+ LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class");
return false;
}
@@ -1180,9 +1127,8 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
- if (log)
- log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
- PrintValue(persistent_load).c_str());
+ LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
+ PrintValue(persistent_load));
alloc->replaceAllUsesWith(persistent_load);
alloc->eraseFromParent();
@@ -1197,23 +1143,16 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
-
InstrList pvar_allocs;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
+ for (Instruction &inst : 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.find_first_of("0123456789") == 1) {
- if (log)
- log->Printf("Rejecting a numeric persistent variable.");
+ LLDB_LOG(log, "Rejecting a numeric persistent variable.");
m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
"$1, ... are reserved for use as result "
@@ -1227,16 +1166,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
}
}
- InstrIterator iter;
-
- for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
- if (!RewritePersistentAlloc(*iter)) {
+ for (Instruction *inst : pvar_allocs) {
+ if (!RewritePersistentAlloc(inst)) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
"the creation of a persistent variable\n");
- if (log)
- log->PutCString(
- "Couldn't rewrite the creation of a persistent variable");
+ LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");
return false;
}
@@ -1245,79 +1180,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
return true;
}
-bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
- if (!initializer)
- return true;
-
- lldb_private::Log *log(
- lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- if (log && log->GetVerbose())
- log->Printf(" MaterializeInitializer(%p, %s)", (void *)data,
- PrintValue(initializer).c_str());
-
- Type *initializer_type = initializer->getType();
-
- if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
- size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
- lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
- llvm::NextPowerOf2(constant_size) * 8);
-
- lldb_private::Status get_data_error;
- return scalar.GetAsMemoryData(data, constant_size,
- lldb_private::endian::InlHostByteOrder(),
- get_data_error) != 0;
- } else if (ConstantDataArray *array_initializer =
- dyn_cast<ConstantDataArray>(initializer)) {
- if (array_initializer->isString()) {
- std::string array_initializer_string = array_initializer->getAsString();
- memcpy(data, array_initializer_string.c_str(),
- m_target_data->getTypeStoreSize(initializer_type));
- } else {
- ArrayType *array_initializer_type = array_initializer->getType();
- Type *array_element_type = array_initializer_type->getElementType();
-
- size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
-
- for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
- Value *operand_value = array_initializer->getOperand(i);
- Constant *operand_constant = dyn_cast<Constant>(operand_value);
-
- if (!operand_constant)
- return false;
-
- if (!MaterializeInitializer(data + (i * element_size),
- operand_constant))
- return false;
- }
- }
- return true;
- } else if (ConstantStruct *struct_initializer =
- dyn_cast<ConstantStruct>(initializer)) {
- StructType *struct_initializer_type = struct_initializer->getType();
- const StructLayout *struct_layout =
- m_target_data->getStructLayout(struct_initializer_type);
-
- for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
- if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
- struct_initializer->getOperand(i)))
- return false;
- }
- return true;
- } else if (isa<ConstantAggregateZero>(initializer)) {
- memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
- return true;
- }
- return false;
-}
-
// This function does not report errors; its callers are responsible.
bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
+ LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));
if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
switch (constant_expr->getOpcode()) {
@@ -1343,25 +1211,26 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
if (!global_variable->hasExternalLinkage())
return true;
- if (log)
- log->Printf("Found global variable \"%s\" without metadata",
- global_variable->getName().str().c_str());
+ LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
+ global_variable->getName());
return false;
}
- std::string name(named_decl->getName().str());
+ llvm::StringRef name(named_decl->getName());
clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
if (value_decl == nullptr)
return false;
- lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
- value_decl->getType());
+ lldb_private::CompilerType compiler_type(
+ lldb_private::ClangASTContext::GetASTContext(
+ &value_decl->getASTContext()),
+ value_decl->getType().getAsOpaquePtr());
const Type *value_type = nullptr;
- if (name[0] == '$') {
+ if (name.startswith("$")) {
// 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
@@ -1381,31 +1250,24 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
if (!value_size)
return false;
- lldb::offset_t value_alignment =
- (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
-
- if (log) {
- log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
- ", align %" PRIu64 "]",
- name.c_str(),
- lldb_private::ClangUtil::GetQualType(compiler_type)
- .getAsString()
- .c_str(),
- PrintType(value_type).c_str(), *value_size, value_alignment);
- }
-
- if (named_decl &&
- !m_decl_map->AddValueToStruct(
- named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
- *value_size, value_alignment)) {
- if (!global_variable->hasExternalLinkage())
- return true;
- else
- return true;
- }
+ llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr);
+ if (!opt_alignment)
+ return false;
+ lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;
+
+ LLDB_LOG(log,
+ "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
+ "align {4}]",
+ name,
+ lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
+ PrintType(value_type), *value_size, value_alignment);
+
+ if (named_decl)
+ m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
+ llvm_value_ptr, *value_size,
+ value_alignment);
} else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
- if (log)
- log->Printf("Function pointers aren't handled right now");
+ LLDB_LOG(log, "Function pointers aren't handled right now");
return false;
}
@@ -1424,14 +1286,12 @@ bool IRForTarget::HandleSymbol(Value *symbol) {
m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
if (symbol_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Symbol \"%s\" had no address", name.GetCString());
+ LLDB_LOG(log, "Symbol \"{0}\" had no address", name);
return false;
}
- if (log)
- log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
+ LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);
Type *symbol_type = symbol->getType();
@@ -1440,9 +1300,8 @@ bool IRForTarget::HandleSymbol(Value *symbol) {
Value *symbol_addr_ptr =
ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
- if (log)
- log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
- PrintValue(symbol_addr_ptr).c_str());
+ LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
+ PrintValue(symbol_addr_ptr));
symbol->replaceAllUsesWith(symbol_addr_ptr);
@@ -1453,14 +1312,12 @@ bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
+ LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));
for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
op_index < num_ops; ++op_index)
- if (!MaybeHandleVariable(Old->getArgOperand(
- op_index))) // conservatively believe that this is a store
- {
+ // conservatively believe that this is a store
+ if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
"one of the arguments of a function call.\n");
@@ -1493,9 +1350,8 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
lldb::addr_t class_ptr =
m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
- if (log)
- log->Printf("Found reference to Objective-C class %s (0x%llx)",
- name_cstr.AsCString(), (unsigned long long)class_ptr);
+ LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
+ (unsigned long long)class_ptr);
if (class_ptr == LLDB_INVALID_ADDRESS)
return false;
@@ -1528,13 +1384,9 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
}
bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
- BasicBlock::iterator ii;
-
std::vector<CallInst *> calls_to_remove;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
-
+ for (Instruction &inst : basic_block) {
CallInst *call = dyn_cast<CallInst>(&inst);
// MaybeHandleCallArguments handles error reporting; we are silent here
@@ -1557,25 +1409,16 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
calls_to_remove.push_back(call);
}
- for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
- ce = calls_to_remove.end();
- ci != ce; ++ci) {
- (*ci)->eraseFromParent();
- }
+ for (CallInst *ci : calls_to_remove)
+ ci->eraseFromParent();
return true;
}
bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
- /////////////////////////////////////////////////////////////////////////
// Prepare the current basic block for execution in the remote process
- //
-
- BasicBlock::iterator ii;
-
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
+ for (Instruction &inst : basic_block) {
CallInst *call = dyn_cast<CallInst>(&inst);
// MaybeHandleCallArguments handles error reporting; we are silent here
@@ -1591,31 +1434,27 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) {
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
for (GlobalVariable &global_var : m_module->globals()) {
- std::string global_name = global_var.getName().str();
+ llvm::StringRef global_name = global_var.getName();
- if (log)
- log->Printf("Examining %s, DeclForGlobalValue returns %p",
- global_name.c_str(),
- static_cast<void *>(DeclForGlobal(&global_var)));
+ LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
+ static_cast<void *>(DeclForGlobal(&global_var)));
- if (global_name.find("OBJC_IVAR") == 0) {
+ if (global_name.startswith("OBJC_IVAR")) {
if (!HandleSymbol(&global_var)) {
- m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C "
- "indirect ivar symbol %s\n",
- global_name.c_str());
+ m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
+ "indirect ivar symbol {0}\n",
+ global_name);
return false;
}
- } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") !=
- global_name.npos) {
+ } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
if (!HandleObjCClass(&global_var)) {
m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
"for an Objective-C static method call\n");
return false;
}
- } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") !=
- global_name.npos) {
+ } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
if (!HandleObjCClass(&global_var)) {
m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
"for an Objective-C static method call\n");
@@ -1624,9 +1463,9 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) {
}
} else if (DeclForGlobal(&global_var)) {
if (!MaybeHandleVariable(&global_var)) {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
- "external variable %s\n",
- global_name.c_str());
+ m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
+ "external variable {0}\n",
+ global_name);
return false;
}
@@ -1637,14 +1476,12 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) {
}
static bool isGuardVariableRef(Value *V) {
- Constant *Old = nullptr;
+ Constant *Old = dyn_cast<Constant>(V);
- if (!(Old = dyn_cast<Constant>(V)))
+ if (!Old)
return false;
- ConstantExpr *CE = nullptr;
-
- if ((CE = dyn_cast<ConstantExpr>(V))) {
+ if (auto CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() != Instruction::BitCast)
return false;
@@ -1653,12 +1490,8 @@ static bool isGuardVariableRef(Value *V) {
GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
- if (!GV || !GV->hasName() ||
- (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
- !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
- {
+ if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName()))
return false;
- }
return true;
}
@@ -1674,20 +1507,12 @@ static void ExciseGuardStore(Instruction *guard_store) {
}
bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
- ///////////////////////////////////////////////////////
// Eliminate any reference to guard variables found.
- //
-
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
InstrList guard_loads;
InstrList guard_stores;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
+ for (Instruction &inst : basic_block) {
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (isGuardVariableRef(load->getPointerOperand()))
@@ -1698,13 +1523,11 @@ bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
guard_stores.push_back(&inst);
}
- InstrIterator iter;
+ for (Instruction *inst : guard_loads)
+ TurnGuardLoadIntoZero(inst);
- for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter)
- TurnGuardLoadIntoZero(*iter);
-
- for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
- ExciseGuardStore(*iter);
+ for (Instruction *inst : guard_stores)
+ ExciseGuardStore(inst);
return true;
}
@@ -1837,8 +1660,7 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
m_decl_map->DoStructLayout();
- if (log)
- log->Printf("Element arrangement:");
+ LLDB_LOG(log, "Element arrangement:");
uint32_t num_elements;
uint32_t element_index;
@@ -1884,9 +1706,9 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
}
if (!iter->getName().equals("_cmd")) {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
+ m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
"after 'self' argument (should take '_cmd')",
- iter->getName().str().c_str());
+ iter->getName());
return false;
}
@@ -1905,15 +1727,14 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
}
if (!argument->getName().equals("$__lldb_arg")) {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
- "argument named '%s' instead of the struct pointer",
- argument->getName().str().c_str());
+ m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
+ "argument named '{0}' instead of the struct pointer",
+ argument->getName());
return false;
}
- if (log)
- log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
+ LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
BasicBlock &entry_block(llvm_function.getEntryBlock());
Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
@@ -1950,13 +1771,11 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
return false;
}
- if (log)
- log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(),
- decl->getNameAsString().c_str(), offset);
+ LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name,
+ decl->getNameAsString(), offset);
if (value) {
- if (log)
- log->Printf(" Replacing [%s]", PrintValue(value).c_str());
+ LLDB_LOG(log, " Replacing [{0}]", PrintValue(value));
FunctionValueCache body_result_maker(
[this, name, offset_type, offset, argument,
@@ -2005,9 +1824,8 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
value->replaceAllUsesWith(
body_result_maker.GetValue(instruction->getParent()->getParent()));
} else {
- if (log)
- log->Printf("Unhandled non-constant type: \"%s\"",
- PrintValue(value).c_str());
+ LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
+ PrintValue(value));
return false;
}
@@ -2016,35 +1834,12 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
}
}
- if (log)
- log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
- (int64_t)alignment, (uint64_t)size);
+ LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
+ (uint64_t)size);
return true;
}
-llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
- uint64_t offset) {
- llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
-
- llvm::Constant *offset_array[1];
-
- offset_array[0] = offset_int;
-
- llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
- llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
- llvm::Type *char_pointer_type = char_type->getPointerTo();
-
- llvm::Constant *reloc_placeholder_bitcast =
- ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
- llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
- char_type, reloc_placeholder_bitcast, offsets);
- llvm::Constant *reloc_bitcast =
- ConstantExpr::getBitCast(reloc_getelementptr, type);
-
- return reloc_bitcast;
-}
-
bool IRForTarget::runOnModule(Module &llvm_module) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -2062,7 +1857,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
oss.flush();
- log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
+ LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
}
Function *const main_function =
@@ -2070,21 +1865,18 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
: m_module->getFunction(m_func_name.GetStringRef());
if (!m_func_name.IsEmpty() && !main_function) {
- if (log)
- log->Printf("Couldn't find \"%s()\" in the module",
- m_func_name.AsCString());
+ LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
- "'%s' in the module",
- m_func_name.AsCString());
+ m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
+ "'{0}' in the module",
+ m_func_name);
return false;
}
if (main_function) {
if (!FixFunctionLinkage(*main_function)) {
- if (log)
- log->Printf("Couldn't fix the linkage for the function");
+ LLDB_LOG(log, "Couldn't fix the linkage for the function");
return false;
}
@@ -2104,8 +1896,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
if (main_function) {
if (!CreateResultVariable(*main_function)) {
- if (log)
- log->Printf("CreateResultVariable() failed");
+ LLDB_LOG(log, "CreateResultVariable() failed");
// CreateResultVariable() reports its own errors, so we don't do so here
@@ -2121,32 +1912,21 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
oss.flush();
- log->Printf("Module after creating the result variable: \n\"%s\"",
- s.c_str());
+ LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
}
- for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
- ++fi) {
- llvm::Function *function = &*fi;
-
- if (function->begin() == function->end())
- continue;
-
- Function::iterator bbi;
-
- for (bbi = function->begin(); bbi != function->end(); ++bbi) {
- if (!RemoveGuards(*bbi)) {
- if (log)
- log->Printf("RemoveGuards() failed");
+ for (llvm::Function &function : *m_module) {
+ for (BasicBlock &bb : function) {
+ if (!RemoveGuards(bb)) {
+ LLDB_LOG(log, "RemoveGuards() failed");
// RemoveGuards() reports its own errors, so we don't do so here
return false;
}
- if (!RewritePersistentAllocs(*bbi)) {
- if (log)
- log->Printf("RewritePersistentAllocs() failed");
+ if (!RewritePersistentAllocs(bb)) {
+ LLDB_LOG(log, "RewritePersistentAllocs() failed");
// RewritePersistentAllocs() reports its own errors, so we don't do so
// here
@@ -2154,9 +1934,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
return false;
}
- if (!RemoveCXAAtExit(*bbi)) {
- if (log)
- log->Printf("RemoveCXAAtExit() failed");
+ if (!RemoveCXAAtExit(bb)) {
+ LLDB_LOG(log, "RemoveCXAAtExit() failed");
// RemoveCXAAtExit() reports its own errors, so we don't do so here
@@ -2170,24 +1949,17 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
//
if (!RewriteObjCConstStrings()) {
- if (log)
- log->Printf("RewriteObjCConstStrings() failed");
+ LLDB_LOG(log, "RewriteObjCConstStrings() failed");
// RewriteObjCConstStrings() reports its own errors, so we don't do so here
return false;
}
- for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
- ++fi) {
- llvm::Function *function = &*fi;
-
- for (llvm::Function::iterator bbi = function->begin(),
- bbe = function->end();
- bbi != bbe; ++bbi) {
- if (!RewriteObjCSelectors(*bbi)) {
- if (log)
- log->Printf("RewriteObjCSelectors() failed");
+ for (llvm::Function &function : *m_module) {
+ for (llvm::BasicBlock &bb : function) {
+ if (!RewriteObjCSelectors(bb)) {
+ LLDB_LOG(log, "RewriteObjCSelectors() failed");
// RewriteObjCSelectors() reports its own errors, so we don't do so
// here
@@ -2195,9 +1967,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
return false;
}
- if (!RewriteObjCClassReferences(*bbi)) {
- if (log)
- log->Printf("RewriteObjCClassReferences() failed");
+ if (!RewriteObjCClassReferences(bb)) {
+ LLDB_LOG(log, "RewriteObjCClassReferences() failed");
// RewriteObjCClasses() reports its own errors, so we don't do so here
@@ -2206,16 +1977,10 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
}
}
- for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
- ++fi) {
- llvm::Function *function = &*fi;
-
- for (llvm::Function::iterator bbi = function->begin(),
- bbe = function->end();
- bbi != bbe; ++bbi) {
- if (!ResolveCalls(*bbi)) {
- if (log)
- log->Printf("ResolveCalls() failed");
+ for (llvm::Function &function : *m_module) {
+ for (BasicBlock &bb : function) {
+ if (!ResolveCalls(bb)) {
+ LLDB_LOG(log, "ResolveCalls() failed");
// ResolveCalls() reports its own errors, so we don't do so here
@@ -2230,8 +1995,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
if (main_function) {
if (!ResolveExternals(*main_function)) {
- if (log)
- log->Printf("ResolveExternals() failed");
+ LLDB_LOG(log, "ResolveExternals() failed");
// ResolveExternals() reports its own errors, so we don't do so here
@@ -2239,8 +2003,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
}
if (!ReplaceVariables(*main_function)) {
- if (log)
- log->Printf("ReplaceVariables() failed");
+ LLDB_LOG(log, "ReplaceVariables() failed");
// ReplaceVariables() reports its own errors, so we don't do so here
@@ -2256,7 +2019,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
oss.flush();
- log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
+ LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
}
return true;
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index f87fd8ac32cb..893620f7f8e0 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -10,6 +10,7 @@
#ifndef liblldb_IRForTarget_h_
#define liblldb_IRForTarget_h_
+#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
@@ -331,27 +332,6 @@ private:
/// a call to a function pointer whose value is the address of the function
/// in the target process.
- /// Write an initializer to a memory array of assumed sufficient size.
- ///
- /// \param[in] data
- /// A pointer to the data to write to.
- ///
- /// \param[in] initializer
- /// The initializer itself.
- ///
- /// \return
- /// True on success; false otherwise
- bool MaterializeInitializer(uint8_t *data, llvm::Constant *initializer);
-
- /// Move an internal variable into the static allocation section.
- ///
- /// \param[in] global_variable
- /// The variable.
- ///
- /// \return
- /// True on success; false otherwise
- bool MaterializeInternalVariable(llvm::GlobalVariable *global_variable);
-
/// Handle a single externally-defined variable
///
/// \param[in] value
@@ -539,20 +519,6 @@ private:
FunctionValueCache &entry_instruction_finder,
lldb_private::Stream &error_stream);
- /// Construct a reference to m_reloc_placeholder with a given type and
- /// offset. This typically happens after inserting data into
- /// m_data_allocator.
- ///
- /// \param[in] type
- /// The type of the value being loaded.
- ///
- /// \param[in] offset
- /// The offset of the value from the base of m_data_allocator.
- ///
- /// \return
- /// The Constant for the reference, usually a ConstantExpr.
- llvm::Constant *BuildRelocation(llvm::Type *type, uint64_t offset);
-
/// Commit the allocation in m_data_allocator and use its final location to
/// replace m_reloc_placeholder.
///
diff --git a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
index 0e959f86fd2a..7553860f2492 100644
--- a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
+++ b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
@@ -9,21 +9,23 @@
#ifndef liblldb_ModuleDependencyCollector_h_
#define liblldb_ModuleDependencyCollector_h_
-#include "lldb/Utility/FileCollector.h"
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileCollector.h"
namespace lldb_private {
class ModuleDependencyCollectorAdaptor
: public clang::ModuleDependencyCollector {
public:
- ModuleDependencyCollectorAdaptor(FileCollector &file_collector)
+ ModuleDependencyCollectorAdaptor(
+ std::shared_ptr<llvm::FileCollector> file_collector)
: clang::ModuleDependencyCollector(""), m_file_collector(file_collector) {
}
void addFile(llvm::StringRef Filename,
llvm::StringRef FileDst = {}) override {
- m_file_collector.AddFile(Filename);
+ if (m_file_collector)
+ m_file_collector->addFile(Filename);
}
bool insertSeen(llvm::StringRef Filename) override { return false; }
@@ -31,7 +33,7 @@ public:
void writeFileMap() override {}
private:
- FileCollector &m_file_collector;
+ std::shared_ptr<llvm::FileCollector> m_file_collector;
};
} // namespace lldb_private
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 6323889c2e09..19a987b0f004 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -14507,6 +14507,7 @@ bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("EmulateInstructionARM");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_lr);
return true;
}
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index d7e8e0491342..3e06fca2504c 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -149,7 +149,8 @@ EmulateInstructionARM64::CreateInstance(const ArchSpec &arch,
InstructionType inst_type) {
if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(
inst_type)) {
- if (arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
+ arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
return new EmulateInstructionARM64(arch);
}
}
@@ -479,6 +480,7 @@ bool EmulateInstructionARM64::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionARM64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(gpr_lr_arm64);
return true;
}
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index cbf3dda7896e..21b6296745bd 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -1150,6 +1150,7 @@ bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionMIPS");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
return true;
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 69f0278d1437..5fabbeb756cc 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -1042,6 +1042,7 @@ bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionMIPS64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
return true;
diff --git a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
index c77fa04fc7d7..4b8d8dd2228c 100644
--- a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
+++ b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
@@ -135,6 +135,7 @@ bool EmulateInstructionPPC64::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionPPC64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(gpr_lr_ppc64le);
return true;
}
diff --git a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
index c8ac04641e68..2e5dd5989e77 100644
--- a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
@@ -264,7 +264,7 @@ bool AddressSanitizerRuntime::NotifyBreakpointHit(
*thread_sp, description, report));
StreamFileSP stream_sp(
- process_sp->GetTarget().GetDebugger().GetOutputFile());
+ 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 "
diff --git a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
index 89f2139db71b..45a3aeeb204e 100644
--- a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
@@ -863,13 +863,11 @@ bool ThreadSanitizerRuntime::NotifyBreakpointHit(
CreateStopReasonWithInstrumentationData(
*thread_sp, stop_reason_description, report));
- StreamFileSP stream_sp(
- process_sp->GetTarget().GetDebugger().GetOutputFile());
- if (stream_sp) {
- stream_sp->Printf("ThreadSanitizer report breakpoint hit. Use 'thread "
- "info -s' to get extended information about the "
- "report.\n");
- }
+ StreamFile &s = process_sp->GetTarget().GetDebugger().GetOutputStream();
+ s.Printf("ThreadSanitizer 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
diff --git a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
index 367098bb448e..50f1d48d03e0 100644
--- a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
@@ -124,7 +124,7 @@ StructuredData::ObjectSP UndefinedBehaviorSanitizerRuntime::RetrieveReportData(
if (!frame_sp)
return StructuredData::ObjectSP();
- StreamFileSP Stream(target.GetDebugger().GetOutputFile());
+ StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP();
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index 140d09ed43cf..fff44123539f 100644
--- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -6,9 +6,8 @@
//
//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/MathExtras.h"
-
+#include "JITLoaderGDB.h"
+#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -26,8 +25,7 @@
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
-
-#include "JITLoaderGDB.h"
+#include "llvm/Support/MathExtras.h"
#include <memory>
@@ -59,21 +57,33 @@ enum EnableJITLoaderGDB {
eEnableJITLoaderGDBOff,
};
-static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] = {
- {eEnableJITLoaderGDBDefault, "default", "Enable JIT compilation interface "
- "for all platforms except macOS"},
- {eEnableJITLoaderGDBOn, "on", "Enable JIT compilation interface"},
- {eEnableJITLoaderGDBOff, "off", "Disable JIT compilation interface"}
- };
+static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] =
+ {
+ {
+ eEnableJITLoaderGDBDefault,
+ "default",
+ "Enable JIT compilation interface for all platforms except macOS",
+ },
+ {
+ eEnableJITLoaderGDBOn,
+ "on",
+ "Enable JIT compilation interface",
+ },
+ {
+ eEnableJITLoaderGDBOff,
+ "off",
+ "Disable JIT compilation interface",
+ },
+};
-static constexpr PropertyDefinition g_properties[] = {
- {"enable", OptionValue::eTypeEnum, true,
- eEnableJITLoaderGDBDefault, nullptr,
- OptionEnumValues(g_enable_jit_loader_gdb_enumerators),
- "Enable GDB's JIT compilation interface (default: enabled on "
- "all platforms except macOS)"}};
+#define LLDB_PROPERTIES_jitloadergdb
+#include "JITLoaderGDBProperties.inc"
-enum { ePropertyEnable, ePropertyEnableJITBreakpoint };
+enum {
+#define LLDB_PROPERTIES_jitloadergdb
+#include "JITLoaderGDBPropertiesEnum.inc"
+ ePropertyEnableJITBreakpoint
+};
class PluginProperties : public Properties {
public:
@@ -83,13 +93,13 @@ public:
PluginProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_jitloadergdb_properties);
}
EnableJITLoaderGDB GetEnable() const {
return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration(
nullptr, ePropertyEnable,
- g_properties[ePropertyEnable].default_uint_value);
+ g_jitloadergdb_properties[ePropertyEnable].default_uint_value);
}
};
@@ -177,8 +187,8 @@ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
return;
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
- if (log)
- log->Printf("JITLoaderGDB::%s looking for JIT register hook", __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s looking for JIT register hook",
+ __FUNCTION__);
addr_t jit_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
@@ -188,14 +198,12 @@ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
m_jit_descriptor_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to find JIT descriptor address",
- __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s failed to find JIT descriptor address",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
Breakpoint *bp =
m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
@@ -211,8 +219,7 @@ bool JITLoaderGDB::JITDebugBreakpointHit(void *baton,
user_id_t break_id,
user_id_t break_loc_id) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
- if (log)
- log->Printf("JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
return instance->ReadJITDescriptor(false);
}
@@ -285,9 +292,8 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
size_t bytes_read = m_process->DoReadMemory(m_jit_descriptor_addr, &jit_desc,
jit_desc_size, error);
if (bytes_read != jit_desc_size || !error.Success()) {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to read JIT descriptor",
- __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT descriptor",
+ __FUNCTION__);
return false;
}
@@ -301,9 +307,8 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
while (jit_relevant_entry != 0) {
jit_code_entry<ptr_t> jit_entry;
if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
- __FUNCTION__, jit_relevant_entry);
+ LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
+ __FUNCTION__, jit_relevant_entry);
return false;
}
@@ -312,10 +317,10 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
ModuleSP module_sp;
if (jit_action == JIT_REGISTER_FN) {
- if (log)
- log->Printf("JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
- " (%" PRIu64 " bytes)",
- __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
+ LLDB_LOGF(log,
+ "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
+ " (%" PRIu64 " bytes)",
+ __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
char jit_name[64];
snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
@@ -331,20 +336,16 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
module_sp->GetObjectFile()->GetSymtab();
m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
- if (module_sp->GetObjectFile()->GetPluginName() ==
- ConstString("mach-o")) {
- ObjectFile *image_object_file = module_sp->GetObjectFile();
- if (image_object_file) {
- const SectionList *section_list =
- image_object_file->GetSectionList();
- if (section_list) {
- uint64_t vmaddrheuristic = 0;
- uint64_t lower = (uint64_t)-1;
- uint64_t upper = 0;
- updateSectionLoadAddress(*section_list, target, symbolfile_addr,
- symbolfile_size, vmaddrheuristic, lower,
- upper);
- }
+ if (auto image_object_file =
+ llvm::dyn_cast<ObjectFileMachO>(module_sp->GetObjectFile())) {
+ const SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ uint64_t vmaddrheuristic = 0;
+ uint64_t lower = (uint64_t)-1;
+ uint64_t upper = 0;
+ updateSectionLoadAddress(*section_list, target, symbolfile_addr,
+ symbolfile_size, vmaddrheuristic, lower,
+ upper);
}
} else {
bool changed = false;
@@ -357,15 +358,14 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
module_list.Append(module_sp);
target.ModulesDidLoad(module_list);
} else {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to load module for "
- "JIT entry at 0x%" PRIx64,
- __FUNCTION__, symbolfile_addr);
+ LLDB_LOGF(log,
+ "JITLoaderGDB::%s failed to load module for "
+ "JIT entry at 0x%" PRIx64,
+ __FUNCTION__, symbolfile_addr);
}
} else if (jit_action == JIT_UNREGISTER_FN) {
- if (log)
- log->Printf("JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
- __FUNCTION__, symbolfile_addr);
+ LLDB_LOGF(log, "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
+ __FUNCTION__, symbolfile_addr);
JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
if (it != m_jit_objects.end()) {
@@ -458,8 +458,8 @@ addr_t JITLoaderGDB::GetSymbolAddress(ModuleList &module_list,
SymbolContextList target_symbols;
Target &target = m_process->GetTarget();
- if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
- target_symbols))
+ module_list.FindSymbolsWithNameAndType(name, symbol_type, target_symbols);
+ if (target_symbols.IsEmpty())
return LLDB_INVALID_ADDRESS;
SymbolContext sym_ctx;
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td b/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td
new file mode 100644
index 000000000000..0493838bc85d
--- /dev/null
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td
@@ -0,0 +1,9 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "jitloadergdb" in {
+ def Enable: Property<"enable", "Enum">,
+ Global,
+ DefaultEnumValue<"eEnableJITLoaderGDBDefault">,
+ EnumValues<"OptionEnumValues(g_enable_jit_loader_gdb_enumerators)">,
+ Desc<"Enable GDB's JIT compilation interface (default: enabled on all platforms except macOS)">;
+}
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 87b5b5947f35..5cfd978774fd 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -17,6 +17,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,16 +40,17 @@ public:
return;
}
- Status err;
- TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(
- &err, lldb::eLanguageTypeC_plus_plus);
-
- if (!err.Success() || !type_system) {
+ auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(
+ lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
+ std::move(err), "Failed to get scratch ClangASTContext");
return;
}
ClangASTContext *clang_ast_context =
- llvm::dyn_cast<ClangASTContext>(type_system);
+ llvm::dyn_cast<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_context) {
return;
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 44b9e5e24ccd..489fa7d0ad91 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -486,8 +486,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp,
lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
"libc++ std::list synthetic children",
- ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"), stl_deref_flags,
- true);
+ // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
+ // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
+ ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
+ "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
+ stl_deref_flags, true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
@@ -547,8 +550,8 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"))),
+ RegularExpression(
+ llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
@@ -566,12 +569,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"),
stl_synth_flags, true);
- AddCXXSummary(
- cpp_category_sp, lldb_private::formatters::LibcxxFunctionSummaryProvider,
- "libc++ std::function summary provider",
- ConstString("^std::__[[:alnum:]]+::function<.+>$"), stl_summary_flags,
- true);
-
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
AddCXXSummary(cpp_category_sp,
@@ -589,11 +586,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::list summary provider",
ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxContainerSummaryProvider,
- "libc++ std::list summary provider",
- ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"),
- stl_summary_flags, true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::list summary provider",
+ // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
+ // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
+ ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
+ "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
+ stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::map summary provider",
@@ -750,38 +750,32 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
false);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(true);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -860,6 +854,14 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
// FIXME because of a bug in the FormattersContainer we need to add a summary
// for both X* and const X* (<rdar://problem/12717717>)
AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider,
+ "char8_t * summary provider", ConstString("char8_t *"), string_flags);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::Char8StringSummaryProvider,
+ "char8_t [] summary provider",
+ ConstString("char8_t \\[[0-9]+\\]"), string_array_flags, true);
+
+ AddCXXSummary(
cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
"char16_t * summary provider", ConstString("char16_t *"), string_flags);
AddCXXSummary(cpp_category_sp,
@@ -896,6 +898,9 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
.SetHideItemNames(true)
.SetShowMembersOneLiner(false);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
+ "char8_t summary provider", ConstString("char8_t"),
+ widechar_flags);
AddCXXSummary(
cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
"char16_t summary provider", ConstString("char16_t"), widechar_flags);
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index 959079070acc..3ea7589d8e4a 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -32,6 +32,31 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+bool lldb_private::formatters::Char8StringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
+ if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(valobj_addr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u8");
+
+ if (!StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options)) {
+ stream.Printf("Summary Unavailable");
+ return true;
+ }
+
+ return true;
+}
+
bool lldb_private::formatters::Char16StringSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
ProcessSP process_sp = valobj.GetProcessSP();
@@ -128,6 +153,32 @@ bool lldb_private::formatters::WCharStringSummaryProvider(
return true;
}
+bool lldb_private::formatters::Char8SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ DataExtractor data;
+ Status error;
+ valobj.GetData(data, error);
+
+ if (error.Fail())
+ return false;
+
+ std::string value;
+ valobj.GetValueAsCString(lldb::eFormatUnicode8, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+ options.SetData(data);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u8");
+ options.SetQuote('\'');
+ options.SetSourceSize(1);
+ options.SetBinaryZeroIsTerminator(false);
+
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options);
+}
+
bool lldb_private::formatters::Char16SummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
DataExtractor data;
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
index 92bef2382eac..35498b3b568f 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
@@ -16,6 +16,9 @@
namespace lldb_private {
namespace formatters {
+bool Char8StringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char8_t*
+
bool Char16StringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // char16_t* and unichar*
@@ -27,6 +30,9 @@ bool Char32StringSummaryProvider(
bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // wchar_t*
+bool Char8SummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char8_t
+
bool Char16SummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // char16_t and unichar
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 815dafb6c724..78c453cd1b3c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -30,8 +30,15 @@ public:
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ // Value objects created from raw data (i.e. in a different cluster) must
+ // be referenced via shared pointer to keep them alive, however.
std::vector<ValueObjectSP> m_elements;
- ValueObjectSP m_first;
+ ValueObject* m_first = nullptr;
CompilerType m_bool_type;
ByteOrder m_byte_order = eByteOrderInvalid;
uint8_t m_byte_size = 0;
@@ -50,7 +57,7 @@ BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj)
bool BitsetFrontEnd::Update() {
m_elements.clear();
- m_first.reset();
+ m_first = nullptr;
TargetSP target_sp = m_backend.GetTargetSP();
if (!target_sp)
@@ -63,7 +70,7 @@ bool BitsetFrontEnd::Update() {
m_elements.assign(size, ValueObjectSP());
- m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true);
+ m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true).get();
return false;
}
@@ -86,7 +93,7 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
chunk = m_first->GetChildAtIndex(idx / *bit_size, true);
} else {
type = m_first->GetCompilerType();
- chunk = m_first;
+ chunk = m_first->GetSP();
}
if (!type || !chunk)
return {};
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
index 116021588848..b1ad171d0b0c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
@@ -31,7 +31,6 @@ public:
private:
size_t m_size = 0;
- ValueObjectSP m_base_sp;
};
} // namespace
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
index 4b72089c6ba2..2f06d684f953 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
@@ -38,16 +38,21 @@ public:
}
private:
- ValueObjectSP m_container_sp;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ ValueObject* m_container_sp = nullptr;
};
} // namespace
bool QueueFrontEnd::Update() {
- m_container_sp.reset();
+ m_container_sp = nullptr;
ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true);
if (!c_sp)
return false;
- m_container_sp = c_sp->GetSyntheticValue();
+ m_container_sp = c_sp->GetSyntheticValue().get();
return false;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
index 8da7460f2275..45294e25f0f5 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
@@ -30,47 +30,58 @@ public:
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
- std::vector<ValueObjectSP> m_elements;
- ValueObjectSP m_base_sp;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ std::vector<ValueObject*> m_elements;
+ ValueObject* m_base = nullptr;
};
}
bool TupleFrontEnd::Update() {
m_elements.clear();
- m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
- if (! m_base_sp) {
+ m_base = nullptr;
+
+ ValueObjectSP base_sp;
+ base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
+ if (!base_sp) {
// Pre r304382 name of the base element.
- m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
+ base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
}
- if (! m_base_sp)
+ if (!base_sp)
return false;
- m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(),
- ValueObjectSP());
+ m_base = base_sp.get();
+ m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(),
+ nullptr);
return false;
}
ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) {
if (idx >= m_elements.size())
return ValueObjectSP();
- if (!m_base_sp)
+ if (!m_base)
return ValueObjectSP();
if (m_elements[idx])
- return m_elements[idx];
+ return m_elements[idx]->GetSP();
CompilerType holder_type =
- m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
+ m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
if (!holder_type)
return ValueObjectSP();
- ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true);
+ ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx, true);
if (!holder_sp)
return ValueObjectSP();
ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true);
if (elem_sp)
m_elements[idx] =
- elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str()));
+ elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get();
- return m_elements[idx];
+ if (m_elements[idx])
+ return m_elements[idx]->GetSP();
+ return ValueObjectSP();
}
SyntheticChildrenFrontEnd *
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
index 491cf048e459..62945bd3ce80 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
@@ -184,7 +184,6 @@ public:
private:
size_t m_size = 0;
- ValueObjectSP m_base_sp;
};
} // namespace
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
index 66624e5beb6d..0ac7b8f8e02b 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
@@ -37,7 +37,12 @@ public:
size_t GetIndexOfChildWithName(ConstString name) override;
private:
- std::vector<ValueObjectSP> m_members;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ std::vector<ValueObject*> m_members;
};
} // end of anonymous namespace
@@ -72,7 +77,7 @@ bool LibStdcppTupleSyntheticFrontEnd::Update() {
if (value_sp) {
StreamString name;
name.Printf("[%zd]", m_members.size());
- m_members.push_back(value_sp->Clone(ConstString(name.GetString())));
+ m_members.push_back(value_sp->Clone(ConstString(name.GetString())).get());
}
}
}
@@ -85,8 +90,8 @@ bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; }
lldb::ValueObjectSP
LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
- if (idx < m_members.size())
- return m_members[idx];
+ if (idx < m_members.size() && m_members[idx])
+ return m_members[idx]->GetSP();
return lldb::ValueObjectSP();
}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index 3860f960cb3d..cceb511cdc46 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -39,9 +39,14 @@ public:
bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
private:
- ValueObjectSP m_ptr_obj;
- ValueObjectSP m_obj_obj;
- ValueObjectSP m_del_obj;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ ValueObject* m_ptr_obj = nullptr;
+ ValueObject* m_obj_obj = nullptr;
+ ValueObject* m_del_obj = nullptr;
ValueObjectSP GetTuple();
};
@@ -92,17 +97,17 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
if (ptr_obj)
- m_ptr_obj = ptr_obj->Clone(ConstString("pointer"));
+ m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
if (del_obj)
- m_del_obj = del_obj->Clone(ConstString("deleter"));
+ 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"));
+ m_obj_obj = obj_obj->Clone(ConstString("object")).get();
}
}
@@ -113,12 +118,12 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
lldb::ValueObjectSP
LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
- if (idx == 0)
- return m_ptr_obj;
- if (idx == 1)
- return m_del_obj;
- if (idx == 2)
- return m_obj_obj;
+ if (idx == 0 && m_ptr_obj)
+ 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();
return lldb::ValueObjectSP();
}
diff --git a/source/Plugins/Language/ObjC/CoreMedia.cpp b/source/Plugins/Language/ObjC/CoreMedia.cpp
index d19290ec56fb..247429da1b06 100644
--- a/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -10,6 +10,7 @@
#include "CoreMedia.h"
#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
@@ -25,18 +26,21 @@ bool lldb_private::formatters::CMTimeSummaryProvider(
if (!type.IsValid())
return false;
- TypeSystem *type_system =
+ auto type_system_or_err =
valobj.GetExecutionContextRef()
.GetTargetSP()
- ->GetScratchTypeSystemForLanguage(nullptr, lldb::eLanguageTypeC);
- if (!type_system)
+ ->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
+ std::move(err), "Failed to get scratch type system");
return false;
-
+ }
// fetch children by offset to compensate for potential lack of debug info
- auto int64_ty =
- type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
- auto int32_ty =
- type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
+ auto int64_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
+ eEncodingSint, 64);
+ auto int32_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
+ eEncodingSint, 32);
auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index 404dabf2870c..7219c016dfd1 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -461,12 +461,13 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontE
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_id_type() {
if (valobj_sp) {
- clang::ASTContext *ast = valobj_sp->GetExecutionContextRef()
- .GetTargetSP()
- ->GetScratchClangASTContext()
- ->getASTContext();
- if (ast)
- m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy);
+ auto *clang_ast_context = valobj_sp->GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchClangASTContext();
+ if (clang_ast_context)
+ m_id_type = CompilerType(
+ clang_ast_context,
+ clang_ast_context->getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr());
if (valobj_sp->GetProcessSP())
m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
}
@@ -609,12 +610,13 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
if (valobj_sp) {
CompilerType type = valobj_sp->GetCompilerType();
if (type) {
- ClangASTContext *ast = valobj_sp->GetExecutionContextRef()
- .GetTargetSP()
- ->GetScratchClangASTContext();
- if (ast)
- m_id_type = CompilerType(ast->getASTContext(),
- ast->getASTContext()->ObjCBuiltinIdTy);
+ auto *clang_ast_context = valobj_sp->GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchClangASTContext();
+ if (clang_ast_context)
+ m_id_type = CompilerType(clang_ast_context,
+ clang_ast_context->getASTContext()
+ ->ObjCBuiltinIdTy.getAsOpaquePtr());
}
}
}
diff --git a/source/Plugins/Language/ObjC/NSDictionary.h b/source/Plugins/Language/ObjC/NSDictionary.h
index ecb3fccdf877..44d56f9c2c68 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.h
+++ b/source/Plugins/Language/ObjC/NSDictionary.h
@@ -68,10 +68,10 @@ public:
};
typedef Matcher::UP MatcherUP;
- MatcherUP GetFullMatch(ConstString n) { return llvm::make_unique<Full>(n); }
+ MatcherUP GetFullMatch(ConstString n) { return std::make_unique<Full>(n); }
MatcherUP GetPrefixMatch(ConstString p) {
- return llvm::make_unique<Prefix>(p);
+ return std::make_unique<Prefix>(p);
}
};
diff --git a/source/Plugins/Language/ObjC/NSString.cpp b/source/Plugins/Language/ObjC/NSString.cpp
index 4800c955e5f5..55e129b098dc 100644
--- a/source/Plugins/Language/ObjC/NSString.cpp
+++ b/source/Plugins/Language/ObjC/NSString.cpp
@@ -78,12 +78,12 @@ bool lldb_private::formatters::NSStringSummaryProvider(
return false;
ConstString class_name_cs = descriptor->GetClassName();
- const char *class_name = class_name_cs.GetCString();
+ llvm::StringRef class_name = class_name_cs.GetStringRef();
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
- bool is_tagged_ptr = (0 == strcmp(class_name, "NSTaggedPointerString")) &&
+ bool is_tagged_ptr = class_name == "NSTaggedPointerString" &&
descriptor->GetTaggedPointerInfo();
// for a tagged pointer, the descriptor has everything we need
if (is_tagged_ptr)
@@ -111,7 +111,7 @@ bool lldb_private::formatters::NSStringSummaryProvider(
bool is_inline = (info_bits & 0x60) == 0;
bool has_explicit_length = (info_bits & (1 | 4)) != 4;
bool is_unicode = (info_bits & 0x10) == 0x10;
- bool is_path_store = strcmp(class_name, "NSPathStore2") == 0;
+ bool is_path_store = class_name == "NSPathStore2";
bool has_null = (info_bits & 8) == 8;
size_t explicit_length = 0;
@@ -135,14 +135,14 @@ bool lldb_private::formatters::NSStringSummaryProvider(
}
}
- if (strcmp(class_name, "NSString") && strcmp(class_name, "CFStringRef") &&
- strcmp(class_name, "CFMutableStringRef") &&
- strcmp(class_name, "__NSCFConstantString") &&
- strcmp(class_name, "__NSCFString") &&
- strcmp(class_name, "NSCFConstantString") &&
- strcmp(class_name, "NSCFString") && strcmp(class_name, "NSPathStore2")) {
+ const llvm::StringSet<> supported_string_classes = {
+ "NSString", "CFMutableStringRef",
+ "CFStringRef", "__NSCFConstantString",
+ "__NSCFString", "NSCFConstantString",
+ "NSCFString", "NSPathStore2"};
+ if (supported_string_classes.count(class_name) == 0) {
// not one of us - but tell me class name
- stream.Printf("class name = %s", class_name);
+ stream.Printf("class name = %s", class_name_cs.GetCString());
return true;
}
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index f9ab18688de7..c5bfb5747c13 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/Threading.h"
+#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
#include "CF.h"
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index b392282c3eb1..f38014505a8b 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -231,7 +231,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
SymbolContextList scl;
target.GetImages().FindSymbolsMatchingRegExAndType(
- RegularExpression{R"(^)" + func_to_match}, eSymbolTypeAny, scl, true);
+ RegularExpression{R"(^)" + func_to_match}, eSymbolTypeAny, scl);
// Case 1,2 or 3
if (scl.GetSize() >= 1) {
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 41f38a4e3dcd..02e62a263286 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -79,11 +79,10 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
if (name && strstr(name, vtable_demangled_prefix) == name) {
Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("0x%16.16" PRIx64
- ": static-type = '%s' has vtable symbol '%s'\n",
- original_ptr, in_value.GetTypeName().GetCString(),
- name);
+ 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);
@@ -96,87 +95,81 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
const bool exact_match = true;
TypeList class_types;
- uint32_t num_matches = 0;
// 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) {
- num_matches = sc.module_sp->FindTypes(
- ConstString(lookup_name), exact_match, 1,
- searched_symbol_files, class_types);
- }
+ 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 (num_matches == 0) {
- num_matches = target.GetImages().FindTypes(
- nullptr, ConstString(lookup_name), exact_match, UINT32_MAX,
- searched_symbol_files, class_types);
- }
+ 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 (num_matches == 0) {
- if (log)
- log->Printf("0x%16.16" PRIx64 ": is not dynamic\n",
- original_ptr);
+ if (class_types.Empty()) {
+ LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
+ original_ptr);
return TypeAndOrName();
}
- if (num_matches == 1) {
+ if (class_types.GetSize() == 1) {
type_sp = class_types.GetTypeAtIndex(0);
if (type_sp) {
if (ClangASTContext::IsCXXClassType(
type_sp->GetForwardCompilerType())) {
- if (log)
- log->Printf(
- "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());
+ 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 if (num_matches > 1) {
+ } else {
size_t i;
if (log) {
- for (i = 0; i < num_matches; i++) {
+ for (i = 0; i < class_types.GetSize(); i++) {
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp) {
- if (log)
- log->Printf(
- "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());
+ 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 < num_matches; i++) {
+ for (i = 0; i < class_types.GetSize(); i++) {
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp) {
if (ClangASTContext::IsCXXClassType(
type_sp->GetForwardCompilerType())) {
- if (log)
- log->Printf(
- "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());
+ 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 && i == num_matches) {
- log->Printf(
- "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());
+ 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());
}
}
if (type_info)
@@ -351,7 +344,7 @@ protected:
bool demangled_any = false;
bool error_any = false;
for (auto &entry : command.entries()) {
- if (entry.ref.empty())
+ if (entry.ref().empty())
continue;
// the actual Mangled class should be strict about this, but on the
@@ -359,21 +352,21 @@ protected:
// they will come out with an extra underscore - be willing to strip this
// on behalf of the user. This is the moral equivalent of the -_/-n
// options to c++filt
- auto name = entry.ref;
+ auto name = entry.ref();
if (name.startswith("__Z"))
name = name.drop_front();
- Mangled mangled(name, true);
+ Mangled mangled(name);
if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) {
ConstString demangled(
mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
demangled_any = true;
- result.AppendMessageWithFormat("%s ---> %s\n", entry.ref.str().c_str(),
+ result.AppendMessageWithFormat("%s ---> %s\n", entry.c_str(),
demangled.GetCString());
} else {
error_any = true;
result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n",
- entry.ref.str().c_str());
+ entry.ref().str().c_str());
}
}
@@ -471,8 +464,8 @@ lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() {
if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
// Limit the number of modules that are searched for these breakpoints for
// Apple binaries.
- filter_modules.Append(FileSpec("libc++abi.dylib"));
- filter_modules.Append(FileSpec("libSystem.B.dylib"));
+ filter_modules.EmplaceBack("libc++abi.dylib");
+ filter_modules.EmplaceBack("libSystem.B.dylib");
}
return target.GetSearchFilterForModuleList(&filter_modules);
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 18f2a1829a41..1f27a4f0b3ed 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -38,12 +38,13 @@ public:
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
- log->Printf("AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%"
- "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
- current_id,
- static_cast<void *>(&decl_ctx->getParentASTContext()),
- name.getAsString().c_str(), decl_ctx->getDeclKindName(),
- static_cast<const void *>(decl_ctx));
+ LLDB_LOGF(log,
+ "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%"
+ "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
+ current_id,
+ static_cast<void *>(&decl_ctx->getParentASTContext()),
+ name.getAsString().c_str(), decl_ctx->getDeclKindName(),
+ static_cast<const void *>(decl_ctx));
}
do {
@@ -77,19 +78,20 @@ public:
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
- log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on "
- "(ASTContext*)%p Completing (TagDecl*)%p named %s",
- current_id, static_cast<void *>(&tag_decl->getASTContext()),
- static_cast<void *>(tag_decl),
- tag_decl->getName().str().c_str());
-
- log->Printf(" AOEAS::CT[%u] Before:", current_id);
+ LLDB_LOGF(log,
+ "AppleObjCExternalASTSource::CompleteType[%u] on "
+ "(ASTContext*)%p Completing (TagDecl*)%p named %s",
+ current_id, static_cast<void *>(&tag_decl->getASTContext()),
+ static_cast<void *>(tag_decl),
+ tag_decl->getName().str().c_str());
+
+ LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id);
ASTDumper dumper((clang::Decl *)tag_decl);
dumper.ToLog(log, " [CT] ");
}
if (log) {
- log->Printf(" AOEAS::CT[%u] After:", current_id);
+ LLDB_LOGF(log, " AOEAS::CT[%u] After:", current_id);
ASTDumper dumper((clang::Decl *)tag_decl);
dumper.ToLog(log, " [CT] ");
}
@@ -104,14 +106,15 @@ public:
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
- log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on "
- "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
- current_id,
- static_cast<void *>(&interface_decl->getASTContext()),
- static_cast<void *>(interface_decl),
- interface_decl->getName().str().c_str());
-
- log->Printf(" AOEAS::CT[%u] Before:", current_id);
+ LLDB_LOGF(log,
+ "AppleObjCExternalASTSource::CompleteType[%u] on "
+ "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
+ current_id,
+ static_cast<void *>(&interface_decl->getASTContext()),
+ static_cast<void *>(interface_decl),
+ interface_decl->getName().str().c_str());
+
+ LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id);
ASTDumper dumper((clang::Decl *)interface_decl);
dumper.ToLog(log, " [CT] ");
}
@@ -119,7 +122,7 @@ public:
m_decl_vendor.FinishDecl(interface_decl);
if (log) {
- log->Printf(" [CT] After:");
+ LLDB_LOGF(log, " [CT] After:");
ASTDumper dumper((clang::Decl *)interface_decl);
dumper.ToLog(log, " [CT] ");
}
@@ -148,12 +151,13 @@ private:
};
AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime)
- : DeclVendor(), m_runtime(runtime), m_ast_ctx(runtime.GetProcess()
- ->GetTarget()
- .GetArchitecture()
- .GetTriple()
- .getTriple()
- .c_str()),
+ : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime),
+ m_ast_ctx(runtime.GetProcess()
+ ->GetTarget()
+ .GetArchitecture()
+ .GetTriple()
+ .getTriple()
+ .c_str()),
m_type_realizer_sp(m_runtime.GetEncodingToType()) {
m_external_source = new AppleObjCExternalASTSource(*this);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
@@ -462,8 +466,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
clang::ObjCMethodDecl *method_decl =
method_type.BuildMethod(interface_decl, name, true, m_type_realizer_sp);
- if (log)
- log->Printf("[ AOTV::FD] Instance method [%s] [%s]", name, types);
+ LLDB_LOGF(log, "[ AOTV::FD] Instance method [%s] [%s]", name, types);
if (method_decl)
interface_decl->addDecl(method_decl);
@@ -481,8 +484,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(
interface_decl, name, false, m_type_realizer_sp);
- if (log)
- log->Printf("[ AOTV::FD] Class method [%s] [%s]", name, types);
+ LLDB_LOGF(log, "[ AOTV::FD] Class method [%s] [%s]", name, types);
if (method_decl)
interface_decl->addDecl(method_decl);
@@ -498,10 +500,9 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
const bool for_expression = false;
- if (log)
- log->Printf(
- "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64, name,
- type, offset_ptr);
+ LLDB_LOGF(log,
+ "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64,
+ name, type, offset_ptr);
CompilerType ivar_type = m_runtime.GetEncodingToType()->RealizeType(
m_ast_ctx, type, for_expression);
@@ -527,9 +528,10 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
if (log) {
ASTDumper method_dumper((clang::Decl *)interface_decl);
- log->Printf("[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
- "interface for %s",
- descriptor->GetClassName().AsCString());
+ LLDB_LOGF(log,
+ "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
+ "interface for %s",
+ descriptor->GetClassName().AsCString());
}
if (!descriptor->Describe(superclass_func, instance_method_func,
@@ -539,7 +541,8 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
if (log) {
ASTDumper method_dumper((clang::Decl *)interface_decl);
- log->Printf(
+ LLDB_LOGF(
+ log,
"[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
method_dumper.ToLog(log, " [AOTV::FD] ");
@@ -558,10 +561,9 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
Log *log(GetLogIfAllCategoriesSet(
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
- if (log)
- log->Printf("AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )",
- current_id, (const char *)name.AsCString(),
- append ? "true" : "false", max_matches);
+ LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )",
+ current_id, (const char *)name.AsCString(),
+ append ? "true" : "false", max_matches);
if (!append)
decls.clear();
@@ -595,24 +597,25 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
if (metadata)
isa_value = metadata->GetISAPtr();
- log->Printf("AOCTV::FT [%u] Found %s (isa 0x%" PRIx64
- ") in the ASTContext",
- current_id, dumper.GetCString(), isa_value);
+ LLDB_LOGF(log,
+ "AOCTV::FT [%u] Found %s (isa 0x%" PRIx64
+ ") in the ASTContext",
+ current_id, dumper.GetCString(), isa_value);
}
decls.push_back(result_iface_decl);
ret++;
break;
} else {
- if (log)
- log->Printf("AOCTV::FT [%u] There's something in the ASTContext, but "
- "it's not something we know about",
- current_id);
+ LLDB_LOGF(log,
+ "AOCTV::FT [%u] There's something in the ASTContext, but "
+ "it's not something we know about",
+ current_id);
break;
}
} else if (log) {
- log->Printf("AOCTV::FT [%u] Couldn't find %s in the ASTContext",
- current_id, name.AsCString());
+ LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find %s in the ASTContext",
+ current_id, name.AsCString());
}
// It's not. If it exists, we have to put it into our ASTContext.
@@ -620,8 +623,7 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
if (!isa) {
- if (log)
- log->Printf("AOCTV::FT [%u] Couldn't find the isa", current_id);
+ LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find the isa", current_id);
break;
}
@@ -629,10 +631,10 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
clang::ObjCInterfaceDecl *iface_decl = GetDeclForISA(isa);
if (!iface_decl) {
- if (log)
- log->Printf("AOCTV::FT [%u] Couldn't get the Objective-C interface for "
- "isa 0x%" PRIx64,
- current_id, (uint64_t)isa);
+ LLDB_LOGF(log,
+ "AOCTV::FT [%u] Couldn't get the Objective-C interface for "
+ "isa 0x%" PRIx64,
+ current_id, (uint64_t)isa);
break;
}
@@ -641,8 +643,8 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
clang::QualType new_iface_type =
ast_ctx->getObjCInterfaceType(iface_decl);
ASTDumper dumper(new_iface_type);
- log->Printf("AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")", current_id,
- dumper.GetCString(), (uint64_t)isa);
+ LLDB_LOGF(log, "AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")",
+ current_id, dumper.GetCString(), (uint64_t)isa);
}
decls.push_back(iface_decl);
@@ -655,8 +657,7 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
clang::ExternalASTMerger::ImporterSource
AppleObjCDeclVendor::GetImporterSource() {
- return {*m_ast_ctx.getASTContext(),
- *m_ast_ctx.getFileManager(),
- m_ast_ctx.GetOriginMap()
- };
+ return clang::ExternalASTMerger::ImporterSource(*m_ast_ctx.getASTContext(),
+ *m_ast_ctx.getFileManager(),
+ m_ast_ctx.GetOriginMap());
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
index 77b30b7fde79..99ca4b748709 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
@@ -10,19 +10,23 @@
#define liblldb_AppleObjCDeclVendor_h_
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/DeclVendor.h"
#include "lldb/lldb-private.h"
+#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
namespace lldb_private {
class AppleObjCExternalASTSource;
-class AppleObjCDeclVendor : public DeclVendor {
+class AppleObjCDeclVendor : public ClangDeclVendor {
public:
AppleObjCDeclVendor(ObjCLanguageRuntime &runtime);
+ static bool classof(const DeclVendor *vendor) {
+ return vendor->GetKind() == eAppleObjCDeclVendor;
+ }
+
uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
std::vector<clang::NamedDecl *> &decls) override;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 52ed3628520f..8ca9ad7b843a 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -223,11 +223,14 @@ Address *AppleObjCRuntime::GetPrintForDebuggerAddr() {
SymbolContextList contexts;
SymbolContext context;
- if ((!modules.FindSymbolsWithNameAndType(ConstString("_NSPrintForDebugger"),
- eSymbolTypeCode, contexts)) &&
- (!modules.FindSymbolsWithNameAndType(ConstString("_CFPrintForDebugger"),
- eSymbolTypeCode, contexts)))
- return nullptr;
+ modules.FindSymbolsWithNameAndType(ConstString("_NSPrintForDebugger"),
+ eSymbolTypeCode, contexts);
+ if (contexts.IsEmpty()) {
+ modules.FindSymbolsWithNameAndType(ConstString("_CFPrintForDebugger"),
+ eSymbolTypeCode, contexts);
+ if (contexts.IsEmpty())
+ return nullptr;
+ }
contexts.GetContextAtIndex(0, context);
@@ -444,10 +447,12 @@ bool AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing() {
SymbolContextList sc_list;
- return target.GetImages().FindSymbolsWithNameAndType(
- s_method_signature, eSymbolTypeCode, sc_list) ||
- target.GetImages().FindSymbolsWithNameAndType(
- s_arclite_method_signature, eSymbolTypeCode, sc_list);
+ target.GetImages().FindSymbolsWithNameAndType(s_method_signature,
+ eSymbolTypeCode, sc_list);
+ if (sc_list.IsEmpty())
+ target.GetImages().FindSymbolsWithNameAndType(s_arclite_method_signature,
+ eSymbolTypeCode, sc_list);
+ return !sc_list.IsEmpty();
}
lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() {
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index c8884fd5c9b9..88bfe2ce0203 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -395,10 +395,11 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
- " from _objc_debug_class_hash to "
- "isa->descriptor cache",
- isa);
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
+ " from _objc_debug_class_hash to "
+ "isa->descriptor cache",
+ isa);
AddClass(isa, descriptor_sp);
}
@@ -417,7 +418,8 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
- log->Printf(
+ LLDB_LOGF(
+ log,
"AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
" from _objc_debug_class_hash to isa->descriptor "
"cache",
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 635eaff637bc..9bdbef393e39 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -582,9 +582,9 @@ protected:
case 0:
break;
case 1: {
- regex_up.reset(new RegularExpression());
- if (!regex_up->Compile(llvm::StringRef::withNullAsEmpty(
- command.GetArgumentAtIndex(0)))) {
+ regex_up.reset(new RegularExpression(
+ llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0))));
+ if (!regex_up->IsValid()) {
result.AppendError(
"invalid argument - please provide a valid regular expression");
result.SetStatus(lldb::eReturnStatusFailed);
@@ -1209,11 +1209,11 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
objc_class_sp = GetClassDescriptorFromISA(isa);
if (isa && !objc_class_sp) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("0x%" PRIx64
- ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
- "not in class descriptor cache 0x%" PRIx64,
- isa_pointer, isa);
+ LLDB_LOGF(log,
+ "0x%" PRIx64
+ ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
+ "not in class descriptor cache 0x%" PRIx64,
+ isa_pointer, isa);
}
}
}
@@ -1317,8 +1317,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
// Read the total number of classes from the hash table
const uint32_t num_classes = hash_table.GetCount();
if (num_classes == 0) {
- if (log)
- log->Printf("No dynamic classes found in gdb_objc_realized_classes.");
+ LLDB_LOGF(log, "No dynamic classes found in gdb_objc_realized_classes.");
return DescriptorMapUpdateResult::Success(0);
}
@@ -1337,17 +1336,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
g_get_dynamic_class_info_body, eLanguageTypeObjC,
g_get_dynamic_class_info_name, error));
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to get Utility Function for implementation lookup: %s",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Failed to get Utility Function for implementation lookup: %s",
+ error.AsCString());
m_get_class_info_code.reset();
} else {
diagnostics.Clear();
if (!m_get_class_info_code->Install(diagnostics, exe_ctx)) {
if (log) {
- log->Printf("Failed to install implementation lookup");
+ LLDB_LOGF(log, "Failed to install implementation lookup");
diagnostics.Dump(log);
}
m_get_class_info_code.reset();
@@ -1372,17 +1370,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
clang_uint32_t_type, arguments, thread_sp, error);
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to make function caller for implementation lookup: %s.",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Failed to make function caller for implementation lookup: %s.",
+ error.AsCString());
return DescriptorMapUpdateResult::Fail();
}
} else {
get_class_info_function = m_get_class_info_code->GetFunctionCaller();
if (!get_class_info_function) {
if (log) {
- log->Printf("Failed to get implementation lookup function caller.");
+ LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
diagnostics.Dump(log);
}
@@ -1399,10 +1396,10 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
if (class_infos_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("unable to allocate %" PRIu32
- " bytes in process for shared cache read",
- class_infos_byte_size);
+ LLDB_LOGF(log,
+ "unable to allocate %" PRIu32
+ " bytes in process for shared cache read",
+ class_infos_byte_size);
return DescriptorMapUpdateResult::Fail();
}
@@ -1451,8 +1448,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
if (results == eExpressionCompleted) {
// The result is the number of ClassInfo structures that were filled in
num_class_infos = return_value.GetScalar().ULong();
- if (log)
- log->Printf("Discovered %u ObjC classes\n", num_class_infos);
+ LLDB_LOGF(log, "Discovered %u ObjC classes\n", num_class_infos);
if (num_class_infos > 0) {
// Read the ClassInfo structures
DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
@@ -1468,13 +1464,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
success = true;
} else {
if (log) {
- log->Printf("Error evaluating our find class name function.");
+ LLDB_LOGF(log, "Error evaluating our find class name function.");
diagnostics.Dump(log);
}
}
} else {
if (log) {
- log->Printf("Error writing function arguments.");
+ LLDB_LOGF(log, "Error writing function arguments.");
diagnostics.Dump(log);
}
}
@@ -1507,17 +1503,18 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
if (isa == 0) {
if (should_log)
- log->Printf(
- "AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
+ LLDB_LOGF(
+ log, "AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
continue;
}
// Check if we already know about this ISA, if we do, the info will never
// change, so we can just skip it.
if (ISAIsCached(isa)) {
if (should_log)
- log->Printf("AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
- ", ignoring this class info",
- isa);
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
+ ", ignoring this class info",
+ isa);
offset += 4;
} else {
// Read the 32 bit hash for the class name
@@ -1536,15 +1533,16 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
AddClass(isa, descriptor_sp, descriptor_sp->GetClassName().AsCString(nullptr));
num_parsed++;
if (should_log)
- log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64
- ", hash=0x%8.8x, name=%s",
- isa, name_hash,
- descriptor_sp->GetClassName().AsCString("<unknown>"));
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV2 added isa=0x%" PRIx64
+ ", hash=0x%8.8x, name=%s",
+ isa, name_hash,
+ descriptor_sp->GetClassName().AsCString("<unknown>"));
}
}
if (should_log)
- log->Printf("AppleObjCRuntimeV2 parsed %" PRIu32 " class infos",
- num_parsed);
+ LLDB_LOGF(log, "AppleObjCRuntimeV2 parsed %" PRIu32 " class infos",
+ num_parsed);
return num_parsed;
}
@@ -1603,7 +1601,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
// use that in our jitted expression. Else fall back to the old
// class_getName.
static ConstString g_class_getName_symbol_name("class_getName");
- static ConstString g_class_getNameRaw_symbol_name("class_getNameRaw");
+ static ConstString g_class_getNameRaw_symbol_name("objc_debug_class_getNameRaw");
ConstString class_name_getter_function_name = g_class_getName_symbol_name;
ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
@@ -1646,17 +1644,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
shared_class_expression.c_str(), eLanguageTypeObjC,
g_get_shared_cache_class_info_name, error));
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to get Utility function for implementation lookup: %s.",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Failed to get Utility function for implementation lookup: %s.",
+ error.AsCString());
m_get_shared_cache_class_info_code.reset();
} else {
diagnostics.Clear();
if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx)) {
if (log) {
- log->Printf("Failed to install implementation lookup.");
+ LLDB_LOGF(log, "Failed to install implementation lookup.");
diagnostics.Dump(log);
}
m_get_shared_cache_class_info_code.reset();
@@ -1703,10 +1700,10 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
if (class_infos_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("unable to allocate %" PRIu32
- " bytes in process for shared cache read",
- class_infos_byte_size);
+ LLDB_LOGF(log,
+ "unable to allocate %" PRIu32
+ " bytes in process for shared cache read",
+ class_infos_byte_size);
return DescriptorMapUpdateResult::Fail();
}
@@ -1757,9 +1754,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
if (results == eExpressionCompleted) {
// The result is the number of ClassInfo structures that were filled in
num_class_infos = return_value.GetScalar().ULong();
- if (log)
- log->Printf("Discovered %u ObjC classes in shared cache\n",
- num_class_infos);
+ LLDB_LOGF(log, "Discovered %u ObjC classes in shared cache\n",
+ num_class_infos);
assert(num_class_infos <= num_classes);
if (num_class_infos > 0) {
if (num_class_infos > num_classes) {
@@ -1786,13 +1782,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
}
} else {
if (log) {
- log->Printf("Error evaluating our find class name function.");
+ LLDB_LOGF(log, "Error evaluating our find class name function.");
diagnostics.Dump(log);
}
}
} else {
if (log) {
- log->Printf("Error writing function arguments.");
+ LLDB_LOGF(log, "Error writing function arguments.");
diagnostics.Dump(log);
}
}
@@ -1827,9 +1823,10 @@ bool AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory(
new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64
- " (%s) from dynamic table to isa->descriptor cache",
- elt.second, elt.first.AsCString());
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64
+ " (%s) from dynamic table to isa->descriptor cache",
+ elt.second, elt.first.AsCString());
AddClass(elt.second, descriptor_sp, elt.first.AsCString());
}
@@ -1912,14 +1909,14 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
DescriptorMapUpdateResult shared_cache_update_result =
UpdateISAToDescriptorMapSharedCache();
- if (log)
- log->Printf("attempted to read objc class data - results: "
- "[dynamic_update]: ran: %s, count: %" PRIu32
- " [shared_cache_update]: ran: %s, count: %" PRIu32,
- dynamic_update_result.m_update_ran ? "yes" : "no",
- dynamic_update_result.m_num_found,
- shared_cache_update_result.m_update_ran ? "yes" : "no",
- shared_cache_update_result.m_num_found);
+ LLDB_LOGF(log,
+ "attempted to read objc class data - results: "
+ "[dynamic_update]: ran: %s, count: %" PRIu32
+ " [shared_cache_update]: ran: %s, count: %" PRIu32,
+ dynamic_update_result.m_update_ran ? "yes" : "no",
+ dynamic_update_result.m_num_found,
+ shared_cache_update_result.m_update_ran ? "yes" : "no",
+ shared_cache_update_result.m_num_found);
// warn if:
// - we could not run either expression
@@ -2032,8 +2029,8 @@ lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(ConstString name) {
if (name_cstr) {
llvm::StringRef name_strref(name_cstr);
- static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
- static const llvm::StringRef class_prefix("OBJC_CLASS_$_");
+ llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
+ llvm::StringRef class_prefix("OBJC_CLASS_$_");
if (name_strref.startswith(ivar_prefix)) {
llvm::StringRef ivar_skipped_prefix =
@@ -2516,8 +2513,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
ObjCISA isa, ObjCISA &ret_isa) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
- if (log)
- log->Printf("AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
+ LLDB_LOGF(log, "AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
if ((isa & ~m_objc_debug_isa_class_mask) == 0)
return false;
@@ -2543,10 +2539,10 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
// read the count again, and update the cache if the count has been
// updated.
if (index > m_indexed_isa_cache.size()) {
- if (log)
- log->Printf("AOCRT::NPI (index = %" PRIu64
- ") exceeds cache (size = %" PRIu64 ")",
- (uint64_t)index, (uint64_t)m_indexed_isa_cache.size());
+ LLDB_LOGF(log,
+ "AOCRT::NPI (index = %" PRIu64
+ ") exceeds cache (size = %" PRIu64 ")",
+ (uint64_t)index, (uint64_t)m_indexed_isa_cache.size());
Process *process(m_runtime.GetProcess());
@@ -2561,9 +2557,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if (error.Fail())
return false;
- if (log)
- log->Printf("AOCRT::NPI (new class count = %" PRIu64 ")",
- (uint64_t)objc_indexed_classes_count);
+ LLDB_LOGF(log, "AOCRT::NPI (new class count = %" PRIu64 ")",
+ (uint64_t)objc_indexed_classes_count);
if (objc_indexed_classes_count > m_indexed_isa_cache.size()) {
// Read the class entries we don't have. We should just read all of
@@ -2581,9 +2576,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if (error.Fail() || bytes_read != buffer.GetByteSize())
return false;
- if (log)
- log->Printf("AOCRT::NPI (read new classes count = %" PRIu64 ")",
- (uint64_t)num_new_classes);
+ LLDB_LOGF(log, "AOCRT::NPI (read new classes count = %" PRIu64 ")",
+ (uint64_t)num_new_classes);
// Append the new entries to the existing cache.
DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
@@ -2600,9 +2594,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if (index > m_indexed_isa_cache.size())
return false;
- if (log)
- log->Printf("AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")",
- (uint64_t)m_indexed_isa_cache[index]);
+ LLDB_LOGF(log, "AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")",
+ (uint64_t)m_indexed_isa_cache[index]);
ret_isa = m_indexed_isa_cache[index];
return (ret_isa != 0); // this is a pointer so 0 is not a valid value
@@ -2647,8 +2640,9 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() {
std::function<lldb::addr_t(ConstString)> get_symbol =
[this](ConstString sym) -> lldb::addr_t {
SymbolContextList sc_list;
- if (GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType(
- sym, lldb::eSymbolTypeData, sc_list) == 1) {
+ GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ sym, lldb::eSymbolTypeData, sc_list);
+ if (sc_list.GetSize() == 1) {
SymbolContext sc;
sc_list.GetContextAtIndex(0, sc);
if (sc.symbol)
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index b3eb09caa86d..379ef3dca86c 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -543,7 +543,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
Status error;
DataExtractor data;
error = argument_values.GetValueAtIndex(0)->GetValueAsData(&exe_ctx, data,
- 0, nullptr);
+ nullptr);
lldb::offset_t offset = 0;
lldb::addr_t region_addr = data.GetPointer(&offset);
@@ -593,7 +593,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions(
if (log) {
StreamString s;
m_regions.back().Dump(s);
- log->Printf("Read vtable region: \n%s", s.GetData());
+ LLDB_LOGF(log, "Read vtable region: \n%s", s.GetData());
}
next_region = m_regions.back().GetNextRegionAddr();
@@ -704,7 +704,7 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler(
// step through any method dispatches. Warn to that effect and get out of
// here.
if (process_sp->CanJIT()) {
- process_sp->GetTarget().GetDebugger().GetErrorFile()->Printf(
+ process_sp->GetTarget().GetDebugger().GetErrorStream().Printf(
"Could not find implementation lookup function \"%s\""
" step in through ObjC method dispatch will not work.\n",
get_impl_name.AsCString());
@@ -779,25 +779,24 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
m_lookup_implementation_function_code, eLanguageTypeObjC,
g_lookup_implementation_function_name, error));
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to get Utility Function for implementation lookup: %s.",
- error.AsCString());
+ LLDB_LOGF(
+ log,
+ "Failed to get Utility Function for implementation lookup: %s.",
+ error.AsCString());
m_impl_code.reset();
return args_addr;
}
if (!m_impl_code->Install(diagnostics, exe_ctx)) {
if (log) {
- log->Printf("Failed to install implementation lookup.");
+ LLDB_LOGF(log, "Failed to install implementation lookup.");
diagnostics.Dump(log);
}
m_impl_code.reset();
return args_addr;
}
} else {
- if (log)
- log->Printf("No method lookup implementation code.");
+ LLDB_LOGF(log, "No method lookup implementation code.");
return LLDB_INVALID_ADDRESS;
}
@@ -811,10 +810,9 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
impl_function_caller = m_impl_code->MakeFunctionCaller(
clang_void_ptr_type, dispatch_values, thread_sp, error);
if (error.Fail()) {
- if (log)
- log->Printf(
- "Error getting function caller for dispatch lookup: \"%s\".",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Error getting function caller for dispatch lookup: \"%s\".",
+ error.AsCString());
return args_addr;
}
} else {
@@ -833,7 +831,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
if (!impl_function_caller->WriteFunctionArguments(
exe_ctx, args_addr, dispatch_values, diagnostics)) {
if (log) {
- log->Printf("Error writing function arguments.");
+ LLDB_LOGF(log, "Error writing function arguments.");
diagnostics.Dump(log);
}
return args_addr;
@@ -934,9 +932,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
lldb::addr_t obj_addr =
argument_values.GetValueAtIndex(obj_index)->GetScalar().ULongLong();
if (obj_addr == 0x0) {
- if (log)
- log->Printf(
- "Asked to step to dispatch to nil object, returning empty plan.");
+ LLDB_LOGF(
+ log,
+ "Asked to step to dispatch to nil object, returning empty plan.");
return ret_plan_sp;
}
@@ -976,13 +974,11 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (super_value.GetScalar().IsValid())
isa_addr = super_value.GetScalar().ULongLong();
else {
- if (log)
- log->Printf("Failed to extract the super class value from the "
- "class in objc_super.");
+ LLDB_LOGF(log, "Failed to extract the super class value from the "
+ "class in objc_super.");
}
} else {
- if (log)
- log->Printf("Failed to extract the class value from objc_super.");
+ LLDB_LOGF(log, "Failed to extract the class value from objc_super.");
}
} else {
// In the objc_msgSendSuper case, we don't get the object
@@ -998,8 +994,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (super_value.GetScalar().IsValid()) {
isa_addr = super_value.GetScalar().ULongLong();
} else {
- if (log)
- log->Printf("Failed to extract the class value from objc_super.");
+ LLDB_LOGF(log, "Failed to extract the class value from objc_super.");
}
}
} else {
@@ -1022,8 +1017,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (isa_value.GetScalar().IsValid()) {
isa_addr = isa_value.GetScalar().ULongLong();
} else {
- if (log)
- log->Printf("Failed to extract the isa value from object.");
+ LLDB_LOGF(log, "Failed to extract the isa value from object.");
}
}
@@ -1033,9 +1027,10 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (isa_addr != LLDB_INVALID_ADDRESS) {
if (log) {
- log->Printf("Resolving call for class - 0x%" PRIx64
- " and selector - 0x%" PRIx64,
- isa_addr, sel_addr);
+ LLDB_LOGF(log,
+ "Resolving call for class - 0x%" PRIx64
+ " and selector - 0x%" PRIx64,
+ isa_addr, sel_addr);
}
ObjCLanguageRuntime *objc_runtime =
ObjCLanguageRuntime::Get(*thread.GetProcess());
@@ -1047,9 +1042,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (impl_addr != LLDB_INVALID_ADDRESS) {
// Yup, it was in the cache, so we can run to that address directly.
- if (log)
- log->Printf("Found implementation address in cache: 0x%" PRIx64,
- impl_addr);
+ LLDB_LOGF(log, "Found implementation address in cache: 0x%" PRIx64,
+ impl_addr);
ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, impl_addr,
stop_others);
@@ -1137,7 +1131,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (log) {
StreamString s;
ret_plan_sp->GetDescription(&s, eDescriptionLevelFull);
- log->Printf("Using ObjC step plan: %s.\n", s.GetData());
+ LLDB_LOGF(log, "Using ObjC step plan: %s.\n", s.GetData());
}
}
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 26654e9212b9..6402e80d6f98 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -18,7 +18,6 @@
#include <vector>
using namespace lldb_private;
-using namespace lldb_utility;
AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
ObjCLanguageRuntime &runtime)
@@ -32,16 +31,14 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
.c_str()));
}
-std::string
-AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer &type) {
+std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) {
StreamString buffer;
while (type.HasAtLeast(1) && type.Peek() != '=')
buffer.Printf("%c", type.Next());
return buffer.GetString();
}
-std::string
-AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) {
+std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) {
StreamString buffer;
while (type.HasAtLeast(1) && type.Peek() != '"')
buffer.Printf("%c", type.Next());
@@ -51,8 +48,7 @@ AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) {
return buffer.GetString();
}
-uint32_t
-AppleObjCTypeEncodingParser::ReadNumber(lldb_utility::StringLexer &type) {
+uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) {
uint32_t total = 0;
while (type.HasAtLeast(1) && isdigit(type.Peek()))
total = 10 * total + (type.Next() - '0');
@@ -68,7 +64,7 @@ AppleObjCTypeEncodingParser::StructElement::StructElement()
AppleObjCTypeEncodingParser::StructElement
AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ StringLexer &type,
bool for_expression) {
StructElement retval;
if (type.NextIf('"'))
@@ -81,25 +77,21 @@ AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx,
return retval;
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildStruct(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
- bool for_expression) {
+clang::QualType AppleObjCTypeEncodingParser::BuildStruct(
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, '{', '}',
clang::TTK_Struct);
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildUnion(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
- bool for_expression) {
+clang::QualType AppleObjCTypeEncodingParser::BuildUnion(
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, '(', ')',
clang::TTK_Union);
}
clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
- clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
- bool for_expression, char opener, char closer, uint32_t kind) {
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression,
+ char opener, char closer, uint32_t kind) {
if (!type.NextIf(opener))
return clang::QualType();
std::string name(ReadStructName(type));
@@ -149,8 +141,9 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
}
ClangASTContext::AddFieldToRecordType(
union_type, element.name.c_str(),
- CompilerType(&ast_ctx, element.type), lldb::eAccessPublic,
- element.bitfield);
+ CompilerType(ClangASTContext::GetASTContext(&ast_ctx),
+ element.type.getAsOpaquePtr()),
+ lldb::eAccessPublic, element.bitfield);
++count;
}
ClangASTContext::CompleteTagDeclarationDefinition(union_type);
@@ -158,10 +151,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
return ClangUtil::GetQualType(union_type);
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
- bool for_expression) {
+clang::QualType AppleObjCTypeEncodingParser::BuildArray(
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
if (!type.NextIf('['))
return clang::QualType();
uint32_t size = ReadNumber(type);
@@ -172,7 +163,9 @@ AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
if (!lldb_ctx)
return clang::QualType();
CompilerType array_type(lldb_ctx->CreateArrayType(
- CompilerType(&ast_ctx, element_type), size, false));
+ CompilerType(ClangASTContext::GetASTContext(&ast_ctx),
+ element_type.getAsOpaquePtr()),
+ size, false));
return ClangUtil::GetQualType(array_type);
}
@@ -182,8 +175,7 @@ AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
// consume but ignore the type info and always return an 'id'; if anything,
// dynamic typing will resolve things for us anyway
clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
- clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
- bool for_expression) {
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
if (!type.NextIf('@'))
return clang::QualType();
@@ -375,7 +367,8 @@ CompilerType AppleObjCTypeEncodingParser::RealizeType(
if (name && name[0]) {
StringLexer lexer(name);
clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
- return CompilerType(&ast_ctx, qual_type);
+ return CompilerType(ClangASTContext::GetASTContext(&ast_ctx),
+ qual_type.getAsOpaquePtr());
}
return CompilerType();
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index e576e8f283f2..590bc4ba9eae 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -15,12 +15,8 @@
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
-namespace lldb_utility {
-class StringLexer;
-}
-
namespace lldb_private {
-
+class StringLexer;
class AppleObjCTypeEncodingParser : public ObjCLanguageRuntime::EncodingToType {
public:
AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime);
@@ -39,41 +35,35 @@ private:
~StructElement() = default;
};
- clang::QualType BuildType(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildType(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression,
uint32_t *bitfield_bit_size = nullptr);
- clang::QualType BuildStruct(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildStruct(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
- clang::QualType BuildAggregate(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildAggregate(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression, char opener, char closer,
uint32_t kind);
- clang::QualType BuildUnion(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildUnion(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
- clang::QualType BuildArray(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildArray(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
- std::string ReadStructName(lldb_utility::StringLexer &type);
+ std::string ReadStructName(StringLexer &type);
- StructElement ReadStructElement(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ StructElement ReadStructElement(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
clang::QualType BuildObjCObjectPointerType(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ StringLexer &type,
bool for_expression);
- uint32_t ReadNumber(lldb_utility::StringLexer &type);
+ uint32_t ReadNumber(StringLexer &type);
- std::string ReadQuotedString(lldb_utility::StringLexer &type);
+ std::string ReadQuotedString(StringLexer &type);
ObjCLanguageRuntime &m_runtime;
};
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index d18435c9c6db..af630eee7265 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -141,17 +141,15 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (target_addr == 0) {
- if (log)
- log->Printf("Got target implementation of 0x0, stopping.");
+ LLDB_LOGF(log, "Got target implementation of 0x0, stopping.");
SetPlanComplete();
return true;
}
if (m_trampoline_handler->AddrIsMsgForward(target_addr)) {
- if (log)
- log->Printf(
- "Implementation lookup returned msgForward function: 0x%" PRIx64
- ", stopping.",
- target_addr);
+ LLDB_LOGF(log,
+ "Implementation lookup returned msgForward function: 0x%" PRIx64
+ ", stopping.",
+ target_addr);
SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(
eSymbolContextEverything);
@@ -167,18 +165,17 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
return false;
}
- if (log)
- log->Printf("Running to ObjC method implementation: 0x%" PRIx64,
- target_addr);
+ LLDB_LOGF(log, "Running to ObjC method implementation: 0x%" PRIx64,
+ target_addr);
ObjCLanguageRuntime *objc_runtime =
ObjCLanguageRuntime::Get(*GetThread().GetProcess());
assert(objc_runtime != nullptr);
objc_runtime->AddToMethodCache(m_isa_addr, m_sel_addr, target_addr);
- if (log)
- log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64
- "} = addr=0x%" PRIx64 " to cache.",
- m_isa_addr, m_sel_addr, target_addr);
+ LLDB_LOGF(log,
+ "Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64
+ "} = addr=0x%" PRIx64 " to cache.",
+ m_isa_addr, m_sel_addr, target_addr);
// Extract the target address from the value:
diff --git a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index 631c15c46ce8..87ae4c2c6c48 100644
--- a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -64,9 +64,10 @@ void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr,
lldb::addr_t impl_addr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log) {
- log->Printf("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64
- " implementation 0x%" PRIx64 ".",
- class_addr, selector, impl_addr);
+ LLDB_LOGF(log,
+ "Caching: class 0x%" PRIx64 " selector 0x%" PRIx64
+ " implementation 0x%" PRIx64 ".",
+ class_addr, selector, impl_addr);
}
m_impl_cache.insert(std::pair<ClassAndSel, lldb::addr_t>(
ClassAndSel(class_addr, selector), impl_addr));
@@ -102,8 +103,8 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
const ModuleList &modules = m_process->GetTarget().GetImages();
SymbolContextList sc_list;
- const size_t matching_symbols =
- modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
+ modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
+ const size_t matching_symbols = sc_list.GetSize();
if (matching_symbols) {
SymbolContext sc;
@@ -120,20 +121,17 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
TypeList types;
llvm::DenseSet<SymbolFile *> searched_symbol_files;
- const uint32_t num_types = module_sp->FindTypes(
- name, exact_match, max_matches, searched_symbol_files, types);
-
- if (num_types) {
- uint32_t i;
- for (i = 0; i < num_types; ++i) {
- TypeSP type_sp(types.GetTypeAtIndex(i));
-
- if (ClangASTContext::IsObjCObjectOrInterfaceType(
- type_sp->GetForwardCompilerType())) {
- if (type_sp->IsCompleteObjCClass()) {
- m_complete_class_cache[name] = type_sp;
- return type_sp;
- }
+ 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));
+
+ if (ClangASTContext::IsObjCObjectOrInterfaceType(
+ type_sp->GetForwardCompilerType())) {
+ if (type_sp->IsCompleteObjCClass()) {
+ m_complete_class_cache[name] = type_sp;
+ return type_sp;
}
}
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index 1925c78ed342..39acd6e9f268 100644
--- a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -17,6 +17,7 @@
#include "llvm/Support/Casting.h"
#include "lldb/Breakpoint/BreakpointPrecondition.h"
+#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Symbol/CompilerType.h"
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
index 60549663db66..b396781e6726 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -140,10 +140,10 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
// We've been using a triple and datalayout of some ARM variant all along,
// so we need to let the backend know that this is no longer the case.
if (log) {
- log->Printf("%s - Changing RS target triple to '%s'", __FUNCTION__,
- real_triple.str().c_str());
- log->Printf(
- "%s - Changing RS datalayout to '%s'", __FUNCTION__,
+ LLDB_LOGF(log, "%s - Changing RS target triple to '%s'", __FUNCTION__,
+ real_triple.str().c_str());
+ LLDB_LOGF(
+ log, "%s - Changing RS datalayout to '%s'", __FUNCTION__,
target_machine->createDataLayout().getStringRepresentation().c_str());
}
module.setTargetTriple(real_triple);
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index c9cd34cf379d..5200749d759f 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -138,9 +138,8 @@ bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
size_t read =
ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), err);
if (read != arg_size || !err.Success()) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 " '%s'",
- __FUNCTION__, uint64_t(i), err.AsCString());
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 " '%s'",
+ __FUNCTION__, uint64_t(i), err.AsCString());
return false;
}
}
@@ -173,8 +172,7 @@ bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
// check the stack alignment was correct (16 byte aligned)
if ((sp & 0xf) != 0x0) {
- if (log)
- log->Printf("%s - stack misaligned", __FUNCTION__);
+ LLDB_LOGF(log, "%s - stack misaligned", __FUNCTION__);
return false;
}
@@ -213,9 +211,8 @@ bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -258,9 +255,8 @@ bool GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -285,15 +281,13 @@ bool GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// arguments passed on the stack
else {
- if (log)
- log->Printf("%s - reading arguments spilled to stack not implemented",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - reading arguments spilled to stack not implemented",
+ __FUNCTION__);
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64, __FUNCTION__,
- uint64_t(i));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64, __FUNCTION__,
+ uint64_t(i));
return false;
}
}
@@ -337,9 +331,8 @@ bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -385,9 +378,8 @@ bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -399,8 +391,7 @@ bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) {
// verify that we have a target
if (!exe_ctx.GetTargetPtr()) {
- if (log)
- log->Printf("%s - invalid target", __FUNCTION__);
+ LLDB_LOGF(log, "%s - invalid target", __FUNCTION__);
return false;
}
@@ -430,9 +421,8 @@ bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) {
default:
// unsupported architecture
if (log) {
- log->Printf(
- "%s - architecture not supported: '%s'", __FUNCTION__,
- exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName());
+ LLDB_LOGF(log, "%s - architecture not supported: '%s'", __FUNCTION__,
+ exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName());
}
return false;
}
@@ -452,28 +442,20 @@ bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) {
// elements fails the contents of &coord are undefined and `false` is
// returned, `true` otherwise
- RegularExpression regex;
- RegularExpression::Match regex_match(3);
-
- bool matched = false;
- if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+),([0-9]+)$")) &&
- regex.Execute(coord_s, &regex_match))
- matched = true;
- else if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+)$")) &&
- regex.Execute(coord_s, &regex_match))
- matched = true;
- else if (regex.Compile(llvm::StringRef("^([0-9]+)$")) &&
- regex.Execute(coord_s, &regex_match))
- matched = true;
-
- if (!matched)
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+
+ if (!RegularExpression("^([0-9]+),([0-9]+),([0-9]+)$")
+ .Execute(coord_s, &matches) &&
+ !RegularExpression("^([0-9]+),([0-9]+)$").Execute(coord_s, &matches) &&
+ !RegularExpression("^([0-9]+)$").Execute(coord_s, &matches))
return false;
- auto get_index = [&](int idx, uint32_t &i) -> bool {
+ auto get_index = [&](size_t idx, uint32_t &i) -> bool {
std::string group;
errno = 0;
- if (regex_match.GetMatchAtIndex(coord_s.str().c_str(), idx + 1, group))
- return !llvm::StringRef(group).getAsInteger<uint32_t>(10, i);
+ if (idx + 1 < matches.size()) {
+ return !llvm::StringRef(matches[idx + 1]).getAsInteger<uint32_t>(10, i);
+ }
return true;
};
@@ -492,9 +474,8 @@ bool SkipPrologue(lldb::ModuleSP &module, Address &addr) {
ConstString name = sc.GetFunctionName();
if (offset)
addr.Slide(offset);
- if (log)
- log->Printf("%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
- name.AsCString(), offset);
+ LLDB_LOGF(log, "%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
+ name.AsCString(), offset);
}
return true;
} else
@@ -809,7 +790,7 @@ RenderScriptRuntime::CreateInstance(Process *process,
// symbol.
Searcher::CallbackReturn
RSBreakpointResolver::SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *, bool) {
+ SymbolContext &context, Address *) {
ModuleSP module = context.module_sp;
if (!module || !IsRenderScriptScriptModule(module))
@@ -839,7 +820,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
Searcher::CallbackReturn
RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
lldb_private::SymbolContext &context,
- Address *, bool) {
+ Address *) {
// We need to have access to the list of reductions currently parsed, as
// reduce names don't actually exist as symbols in a module. They are only
// identifiable by parsing the .rs.info packet, or finding the expand symbol.
@@ -884,14 +865,13 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
if (filter.AddressPasses(address)) {
bool new_bp;
if (!SkipPrologue(module, address)) {
- if (log)
- log->Printf("%s: Error trying to skip prologue", __FUNCTION__);
+ LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__);
}
m_breakpoint->AddLocation(address, &new_bp);
- if (log)
- log->Printf("%s: %s reduction breakpoint on %s in %s", __FUNCTION__,
- new_bp ? "new" : "existing", kernel_name.GetCString(),
- address.GetModule()->GetFileSpec().GetCString());
+ LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s",
+ __FUNCTION__, new_bp ? "new" : "existing",
+ kernel_name.GetCString(),
+ address.GetModule()->GetFileSpec().GetCString());
}
}
}
@@ -900,8 +880,7 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
}
Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
- SearchFilter &filter, SymbolContext &context, Address *addr,
- bool containing) {
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
if (!m_breakpoint)
return eCallbackReturnContinue;
@@ -920,48 +899,43 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
for (auto &name : names) {
const RSScriptGroupDescriptorSP sg = FindScriptGroup(ConstString(name));
if (!sg) {
- if (log)
- log->Printf("%s: could not find script group for %s", __FUNCTION__,
- name.c_str());
+ LLDB_LOGF(log, "%s: could not find script group for %s", __FUNCTION__,
+ name.c_str());
continue;
}
- if (log)
- log->Printf("%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
+ LLDB_LOGF(log, "%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
for (const RSScriptGroupDescriptor::Kernel &k : sg->m_kernels) {
if (log) {
- log->Printf("%s: Adding breakpoint for %s", __FUNCTION__,
- k.m_name.AsCString());
- log->Printf("%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr);
+ LLDB_LOGF(log, "%s: Adding breakpoint for %s", __FUNCTION__,
+ k.m_name.AsCString());
+ LLDB_LOGF(log, "%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr);
}
const lldb_private::Symbol *sym =
module->FindFirstSymbolWithNameAndType(k.m_name, eSymbolTypeCode);
if (!sym) {
- if (log)
- log->Printf("%s: Unable to find symbol for %s", __FUNCTION__,
- k.m_name.AsCString());
+ LLDB_LOGF(log, "%s: Unable to find symbol for %s", __FUNCTION__,
+ k.m_name.AsCString());
continue;
}
if (log) {
- log->Printf("%s: Found symbol name is %s", __FUNCTION__,
- sym->GetName().AsCString());
+ LLDB_LOGF(log, "%s: Found symbol name is %s", __FUNCTION__,
+ sym->GetName().AsCString());
}
auto address = sym->GetAddress();
if (!SkipPrologue(module, address)) {
- if (log)
- log->Printf("%s: Error trying to skip prologue", __FUNCTION__);
+ LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__);
}
bool new_bp;
m_breakpoint->AddLocation(address, &new_bp);
- if (log)
- log->Printf("%s: Placed %sbreakpoint on %s", __FUNCTION__,
- new_bp ? "new " : "", k.m_name.AsCString());
+ LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__,
+ new_bp ? "new " : "", k.m_name.AsCString());
// exit after placing the first breakpoint if we do not intend to stop on
// all kernels making up this script group
@@ -1136,8 +1110,7 @@ void RenderScriptRuntime::HookCallback(RuntimeHook *hook,
ExecutionContext &exe_ctx) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- log->Printf("%s - '%s'", __FUNCTION__, hook->defn->name);
+ LLDB_LOGF(log, "%s - '%s'", __FUNCTION__, hook->defn->name);
if (hook->defn->grabber) {
(this->*(hook->defn->grabber))(hook, exe_ctx);
@@ -1163,19 +1136,18 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
}};
if (!GetArgs(context, args.data(), args.size())) {
- if (log)
- log->Printf("%s - Error while reading the function parameters",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error while reading the function parameters",
+ __FUNCTION__);
return;
} else if (log) {
- log->Printf("%s - groupName : 0x%" PRIx64, __FUNCTION__,
- addr_t(args[eGroupName]));
- log->Printf("%s - groupNameSize: %" PRIu64, __FUNCTION__,
- uint64_t(args[eGroupNameSize]));
- log->Printf("%s - kernel : 0x%" PRIx64, __FUNCTION__,
- addr_t(args[eKernel]));
- log->Printf("%s - kernelCount : %" PRIu64, __FUNCTION__,
- uint64_t(args[eKernelCount]));
+ LLDB_LOGF(log, "%s - groupName : 0x%" PRIx64, __FUNCTION__,
+ addr_t(args[eGroupName]));
+ LLDB_LOGF(log, "%s - groupNameSize: %" PRIu64, __FUNCTION__,
+ uint64_t(args[eGroupNameSize]));
+ LLDB_LOGF(log, "%s - kernel : 0x%" PRIx64, __FUNCTION__,
+ addr_t(args[eKernel]));
+ LLDB_LOGF(log, "%s - kernelCount : %" PRIu64, __FUNCTION__,
+ uint64_t(args[eKernelCount]));
}
// parse script group name
@@ -1187,12 +1159,10 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
m_process->ReadMemory(addr_t(args[eGroupName]), buffer.get(), len, err);
buffer.get()[len] = '\0';
if (!err.Success()) {
- if (log)
- log->Printf("Error reading scriptgroup name from target");
+ LLDB_LOGF(log, "Error reading scriptgroup name from target");
return;
} else {
- if (log)
- log->Printf("Extracted scriptgroup name %s", buffer.get());
+ LLDB_LOGF(log, "Extracted scriptgroup name %s", buffer.get());
}
// write back the script group name
group_name.SetCString(buffer.get());
@@ -1214,9 +1184,8 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
m_scriptGroups.push_back(group);
} else {
// already have this script group
- if (log)
- log->Printf("Attempt to add duplicate script group %s",
- group_name.AsCString());
+ LLDB_LOGF(log, "Attempt to add duplicate script group %s",
+ group_name.AsCString());
return;
}
}
@@ -1234,21 +1203,18 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
size_t read =
m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err);
if (!err.Success() || read != target_ptr_size) {
- if (log)
- log->Printf("Error parsing kernel address %" PRIu64 " in script group",
- i);
+ LLDB_LOGF(log, "Error parsing kernel address %" PRIu64 " in script group",
+ i);
return;
}
- if (log)
- log->Printf("Extracted scriptgroup kernel address - 0x%" PRIx64,
- kernel_addr);
+ LLDB_LOGF(log, "Extracted scriptgroup kernel address - 0x%" PRIx64,
+ kernel_addr);
kernel.m_addr = kernel_addr;
// try to resolve the associated kernel name
if (!ResolveKernelName(kernel.m_addr, kernel.m_name)) {
- if (log)
- log->Printf("Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i,
- kernel_addr);
+ LLDB_LOGF(log, "Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i,
+ kernel_addr);
return;
}
@@ -1261,9 +1227,8 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
// verify this function is a valid kernel
if (IsKnownKernel(base_kernel)) {
kernel.m_name = base_kernel;
- if (log)
- log->Printf("%s - found non expand version '%s'", __FUNCTION__,
- base_kernel.GetCString());
+ LLDB_LOGF(log, "%s - found non expand version '%s'", __FUNCTION__,
+ base_kernel.GetCString());
}
}
}
@@ -1276,15 +1241,13 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
Target &target = m_process->GetTarget();
const BreakpointList &list = target.GetBreakpointList();
const size_t num_breakpoints = list.GetSize();
- if (log)
- log->Printf("Resolving %zu breakpoints", num_breakpoints);
+ LLDB_LOGF(log, "Resolving %zu breakpoints", num_breakpoints);
for (size_t i = 0; i < num_breakpoints; ++i) {
const BreakpointSP bp = list.GetBreakpointAtIndex(i);
if (bp) {
if (bp->MatchesName(group_name.AsCString())) {
- if (log)
- log->Printf("Found breakpoint with name %s",
- group_name.AsCString());
+ LLDB_LOGF(log, "Found breakpoint with name %s",
+ group_name.AsCString());
bp->ResolveBreakpoint();
}
}
@@ -1322,9 +1285,8 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - Error while reading the function parameters",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error while reading the function parameters",
+ __FUNCTION__);
return;
}
@@ -1342,10 +1304,9 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
uint64_t result = 0;
size_t read = m_process->ReadMemory(addr, &result, target_ptr_size, err);
if (read != target_ptr_size || !err.Success()) {
- if (log)
- log->Printf(
- "%s - Error while reading allocation list argument %" PRIu64,
- __FUNCTION__, i);
+ LLDB_LOGF(log,
+ "%s - Error while reading allocation list argument %" PRIu64,
+ __FUNCTION__, i);
} else {
allocs.push_back(result);
}
@@ -1375,8 +1336,8 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
if (log) {
if (alloc->context.isValid() &&
*alloc->context.get() != addr_t(args[eRsContext]))
- log->Printf("%s - Allocation used by multiple contexts",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Allocation used by multiple contexts",
+ __FUNCTION__);
}
alloc->context = addr_t(args[eRsContext]);
}
@@ -1388,7 +1349,7 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
if (log) {
if (script->context.isValid() &&
*script->context.get() != addr_t(args[eRsContext]))
- log->Printf("%s - Script used by multiple contexts", __FUNCTION__);
+ LLDB_LOGF(log, "%s - Script used by multiple contexts", __FUNCTION__);
}
script->context = addr_t(args[eRsContext]);
}
@@ -1416,26 +1377,26 @@ void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook,
bool success = GetArgs(context, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error reading the function parameters.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error reading the function parameters.", __FUNCTION__);
return;
}
if (log) {
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64
- ":%" PRIu64 "bytes.",
- __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
- uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
+ LLDB_LOGF(log,
+ "%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64
+ ":%" PRIu64 "bytes.",
+ __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
+ uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
addr_t script_addr = addr_t(args[eRsScript]);
if (m_scriptMappings.find(script_addr) != m_scriptMappings.end()) {
auto rsm = m_scriptMappings[script_addr];
if (uint64_t(args[eRsId]) < rsm->m_globals.size()) {
auto rsg = rsm->m_globals[uint64_t(args[eRsId])];
- log->Printf("%s - Setting of '%s' within '%s' inferred", __FUNCTION__,
- rsg.m_name.AsCString(),
- rsm->m_module->GetFileSpec().GetFilename().AsCString());
+ LLDB_LOGF(log, "%s - Setting of '%s' within '%s' inferred",
+ __FUNCTION__, rsg.m_name.AsCString(),
+ rsm->m_module->GetFileSpec().GetFilename().AsCString());
}
}
}
@@ -1455,16 +1416,14 @@ void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook,
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error while reading the function parameters",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - error while reading the function parameters",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
- __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsAlloc]), uint64_t(args[eRsForceZero]));
+ LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
+ __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]),
+ uint64_t(args[eRsForceZero]));
AllocationDetails *alloc = CreateAllocation(uint64_t(args[eRsAlloc]));
if (alloc)
@@ -1487,29 +1446,25 @@ void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook,
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error while reading the function parameters.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - error while reading the function parameters.",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__,
- uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]));
+ LLDB_LOGF(log, "%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__,
+ uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]));
for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter) {
auto &allocation_up = *iter; // get the unique pointer
if (allocation_up->address.isValid() &&
*allocation_up->address.get() == addr_t(args[eRsAlloc])) {
m_allocations.erase(iter);
- if (log)
- log->Printf("%s - deleted allocation entry.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - deleted allocation entry.", __FUNCTION__);
return;
}
}
- if (log)
- log->Printf("%s - couldn't find destroyed allocation.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't find destroyed allocation.", __FUNCTION__);
}
void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
@@ -1526,32 +1481,28 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error while reading the function parameters.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - error while reading the function parameters.",
+ __FUNCTION__);
return;
}
std::string res_name;
process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), res_name, err);
if (err.Fail()) {
- if (log)
- log->Printf("%s - error reading res_name: %s.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error reading res_name: %s.", __FUNCTION__,
+ err.AsCString());
}
std::string cache_dir;
process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cache_dir, err);
if (err.Fail()) {
- if (log)
- log->Printf("%s - error reading cache_dir: %s.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error reading cache_dir: %s.", __FUNCTION__,
+ err.AsCString());
}
- if (log)
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
- __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsScript]), res_name.c_str(), cache_dir.c_str());
+ LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
+ __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsScript]),
+ res_name.c_str(), cache_dir.c_str());
if (res_name.size() > 0) {
StreamString strm;
@@ -1566,13 +1517,14 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
script->context = addr_t(args[eRsContext]);
}
- if (log)
- log->Printf("%s - '%s' tagged with context 0x%" PRIx64
- " and script 0x%" PRIx64 ".",
- __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]),
- uint64_t(args[eRsScript]));
+ LLDB_LOGF(log,
+ "%s - '%s' tagged with context 0x%" PRIx64
+ " and script 0x%" PRIx64 ".",
+ __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]));
} else if (log) {
- log->Printf("%s - resource name invalid, Script not tagged.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - resource name invalid, Script not tagged.",
+ __FUNCTION__);
}
}
@@ -1593,8 +1545,7 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
machine != llvm::Triple::ArchType::mipsel &&
machine != llvm::Triple::ArchType::mips64el &&
machine != llvm::Triple::ArchType::x86_64) {
- if (log)
- log->Printf("%s - unable to hook runtime functions.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - unable to hook runtime functions.", __FUNCTION__);
return;
}
@@ -1618,23 +1569,22 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
ConstString(symbol_name), eSymbolTypeCode);
if (!sym) {
if (log) {
- log->Printf("%s - symbol '%s' related to the function %s not found",
- __FUNCTION__, symbol_name, hook_defn->name);
+ LLDB_LOGF(log, "%s - symbol '%s' related to the function %s not found",
+ __FUNCTION__, symbol_name, hook_defn->name);
}
continue;
}
addr_t addr = sym->GetLoadAddress(&target);
if (addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("%s - unable to resolve the address of hook function '%s' "
- "with symbol '%s'.",
- __FUNCTION__, hook_defn->name, symbol_name);
+ LLDB_LOGF(log,
+ "%s - unable to resolve the address of hook function '%s' "
+ "with symbol '%s'.",
+ __FUNCTION__, hook_defn->name, symbol_name);
continue;
} else {
- if (log)
- log->Printf("%s - function %s, address resolved at 0x%" PRIx64,
- __FUNCTION__, hook_defn->name, addr);
+ LLDB_LOGF(log, "%s - function %s, address resolved at 0x%" PRIx64,
+ __FUNCTION__, hook_defn->name, addr);
}
RuntimeHookSP hook(new RuntimeHook());
@@ -1644,11 +1594,12 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
m_runtimeHooks[addr] = hook;
if (log) {
- log->Printf("%s - successfully hooked '%s' in '%s' version %" PRIu64
- " at 0x%" PRIx64 ".",
- __FUNCTION__, hook_defn->name,
- module->GetFileSpec().GetFilename().AsCString(),
- (uint64_t)hook_defn->version, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "%s - successfully hooked '%s' in '%s' version %" PRIu64
+ " at 0x%" PRIx64 ".",
+ __FUNCTION__, hook_defn->name,
+ module->GetFileSpec().GetFilename().AsCString(),
+ (uint64_t)hook_defn->version, (uint64_t)addr);
}
hook_placed[idx] = true;
}
@@ -1661,8 +1612,8 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
const HookDefn &hook_defn = s_runtimeHookDefns[i];
if (hook_defn.kind != kind)
continue;
- log->Printf("%s - function %s was not hooked", __FUNCTION__,
- hook_defn.name);
+ LLDB_LOGF(log, "%s - function %s was not hooked", __FUNCTION__,
+ hook_defn.name);
}
}
}
@@ -1697,11 +1648,11 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) {
if (m_scriptMappings.find(script) != m_scriptMappings.end()) {
// if the module we have stored is different to the one we just received.
if (m_scriptMappings[script] != rsmodule_sp) {
- if (log)
- log->Printf(
- "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
- __FUNCTION__, (uint64_t)script,
- rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ LLDB_LOGF(
+ log,
+ "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
+ __FUNCTION__, (uint64_t)script,
+ rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
}
}
// We don't have a script mapping for the current script.
@@ -1713,11 +1664,9 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) {
rsmodule_sp->m_resname = res_name;
// Add Script/Module pair to map.
m_scriptMappings[script] = rsmodule_sp;
- if (log)
- log->Printf(
- "%s - script %" PRIx64 " associated with rsmodule '%s'.",
- __FUNCTION__, (uint64_t)script,
- rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ LLDB_LOGF(log, "%s - script %" PRIx64 " associated with rsmodule '%s'.",
+ __FUNCTION__, (uint64_t)script,
+ rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
}
}
}
@@ -1730,8 +1679,7 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
StackFrame *frame_ptr,
uint64_t *result) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- log->Printf("%s(%s)", __FUNCTION__, expr);
+ LLDB_LOGF(log, "%s(%s)", __FUNCTION__, expr);
ValueObjectSP expr_result;
EvaluateExpressionOptions options;
@@ -1741,8 +1689,7 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
target.EvaluateExpression(expr, frame_ptr, expr_result, options);
if (!expr_result) {
- if (log)
- log->Printf("%s: couldn't evaluate expression.", __FUNCTION__);
+ LLDB_LOGF(log, "%s: couldn't evaluate expression.", __FUNCTION__);
return false;
}
@@ -1751,16 +1698,14 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
Status err = expr_result->GetError();
// Expression returned is void, so this is actually a success
if (err.GetError() == UserExpression::kNoResult) {
- if (log)
- log->Printf("%s - expression returned void.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression returned void.", __FUNCTION__);
result = nullptr;
return true;
}
- if (log)
- log->Printf("%s - error evaluating expression result: %s", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error evaluating expression result: %s", __FUNCTION__,
+ err.AsCString());
return false;
}
@@ -1769,9 +1714,8 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
*result = expr_result->GetValueAsUnsigned(0, &success);
if (!success) {
- if (log)
- log->Printf("%s - couldn't convert expression result to uint32_t",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't convert expression result to uint32_t",
+ __FUNCTION__);
return false;
}
@@ -1884,8 +1828,7 @@ bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->address.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1895,12 +1838,10 @@ bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->address.get(), x, y, z);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1922,8 +1863,7 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->address.isValid() || !alloc->context.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1933,12 +1873,10 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->context.get(), *alloc->address.get());
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1960,8 +1898,7 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->type_ptr.isValid() || !alloc->context.isValid()) {
- if (log)
- log->Printf("%s - Failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - Failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1983,12 +1920,10 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str,
*alloc->context.get(), bits, *alloc->type_ptr.get());
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2007,10 +1942,10 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
addr_t element_ptr = static_cast<lldb::addr_t>(results[3]);
alloc->element.element_ptr = element_ptr;
- if (log)
- log->Printf("%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32
- ") Element*: 0x%" PRIx64 ".",
- __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr);
+ LLDB_LOGF(log,
+ "%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32
+ ") Element*: 0x%" PRIx64 ".",
+ __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr);
return true;
}
@@ -2024,8 +1959,7 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2042,12 +1976,10 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem,
int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, context,
*elem.element_ptr.get());
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2063,11 +1995,11 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem,
elem.type_vec_size = static_cast<uint32_t>(results[2]);
elem.field_count = static_cast<uint32_t>(results[3]);
- if (log)
- log->Printf("%s - data type %" PRIu32 ", pixel type %" PRIu32
- ", vector size %" PRIu32 ", field count %" PRIu32,
- __FUNCTION__, *elem.type.get(), *elem.type_kind.get(),
- *elem.type_vec_size.get(), *elem.field_count.get());
+ LLDB_LOGF(log,
+ "%s - data type %" PRIu32 ", pixel type %" PRIu32
+ ", vector size %" PRIu32 ", field count %" PRIu32,
+ __FUNCTION__, *elem.type.get(), *elem.type_kind.get(),
+ *elem.type_vec_size.get(), *elem.field_count.get());
// If this Element has subelements then JIT rsaElementGetSubElements() for
// details about its fields
@@ -2084,8 +2016,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2107,12 +2038,10 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
context, field_count, field_count, field_count,
*elem.element_ptr.get(), field_count, field_index);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2120,8 +2049,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
if (!EvalRSExpression(expr_buffer, frame_ptr, &results))
return false;
- if (log)
- log->Printf("%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
+ LLDB_LOGF(log, "%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
switch (expr_index) {
case 0: // Element* of child
@@ -2136,9 +2064,8 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
if (!err.Fail())
child.type_name = ConstString(name);
else {
- if (log)
- log->Printf("%s - warning: Couldn't read field name.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - warning: Couldn't read field name.",
+ __FUNCTION__);
}
break;
}
@@ -2173,8 +2100,7 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
if (!alloc->address.isValid() || !alloc->dimension.isValid() ||
!alloc->data_ptr.isValid() || !alloc->element.datum_size.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2196,9 +2122,8 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
alloc->size = dim_x * dim_y * dim_z * *alloc->element.datum_size.get();
- if (log)
- log->Printf("%s - inferred size of struct allocation %" PRIu32 ".",
- __FUNCTION__, *alloc->size.get());
+ LLDB_LOGF(log, "%s - inferred size of struct allocation %" PRIu32 ".",
+ __FUNCTION__, *alloc->size.get());
return true;
}
@@ -2213,12 +2138,10 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->address.get(), dim_x, dim_y, dim_z);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2242,8 +2165,7 @@ bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->address.isValid() || !alloc->data_ptr.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2253,12 +2175,10 @@ bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->address.get(), 0, 1, 0);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2354,9 +2274,8 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem,
// '#rs_padding_[0-9]+'
if (found && num_children < elem.children.size()) {
const uint32_t size_diff = elem.children.size() - num_children;
- if (log)
- log->Printf("%s - %" PRIu32 " padding struct entries", __FUNCTION__,
- size_diff);
+ LLDB_LOGF(log, "%s - %" PRIu32 " padding struct entries", __FUNCTION__,
+ size_diff);
for (uint32_t i = 0; i < size_diff; ++i) {
ConstString name = elem.children[num_children + i].type_name;
@@ -2377,9 +2296,8 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem,
// Save name of variable in Element.
elem.type_name = valobj_sp->GetTypeName();
- if (log)
- log->Printf("%s - element name set to %s", __FUNCTION__,
- elem.type_name.AsCString());
+ LLDB_LOGF(log, "%s - element name set to %s", __FUNCTION__,
+ elem.type_name.AsCString());
return;
}
@@ -2424,9 +2342,8 @@ void RenderScriptRuntime::SetElementSize(Element &elem) {
elem.padding = padding;
elem.datum_size = data_size + padding;
- if (log)
- log->Printf("%s - element size set to %" PRIu32, __FUNCTION__,
- data_size + padding);
+ LLDB_LOGF(log, "%s - element size set to %" PRIu32, __FUNCTION__,
+ data_size + padding);
}
// Given an allocation, this function copies the allocation contents from
@@ -2439,13 +2356,11 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
// JIT all the allocation details
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info",
+ __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr)) {
- if (log)
- log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__);
return nullptr;
}
}
@@ -2458,9 +2373,8 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
const uint32_t size = *alloc->size.get();
std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
if (!buffer) {
- if (log)
- log->Printf("%s - couldn't allocate a %" PRIu32 " byte buffer",
- __FUNCTION__, size);
+ LLDB_LOGF(log, "%s - couldn't allocate a %" PRIu32 " byte buffer",
+ __FUNCTION__, size);
return nullptr;
}
@@ -2469,10 +2383,10 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
lldb::addr_t data_ptr = *alloc->data_ptr.get();
GetProcess()->ReadMemory(data_ptr, buffer.get(), size, err);
if (err.Fail()) {
- if (log)
- log->Printf("%s - '%s' Couldn't read %" PRIu32
- " bytes of allocation data from 0x%" PRIx64,
- __FUNCTION__, err.AsCString(), size, data_ptr);
+ LLDB_LOGF(log,
+ "%s - '%s' Couldn't read %" PRIu32
+ " bytes of allocation data from 0x%" PRIx64,
+ __FUNCTION__, err.AsCString(), size, data_ptr);
return nullptr;
}
@@ -2493,19 +2407,16 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
if (!alloc)
return false;
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__,
- *alloc->address.get());
+ LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__,
+ *alloc->address.get());
// JIT all the allocation details
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr)) {
- if (log)
- log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__);
return false;
}
}
@@ -2559,9 +2470,8 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
sizeof(AllocationDetails::FileHeader),
sizeof(AllocationDetails::ElementHeader));
- if (log)
- log->Printf("%s - header type %" PRIu32 ", element size %" PRIu32,
- __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size);
+ LLDB_LOGF(log, "%s - header type %" PRIu32 ", element size %" PRIu32,
+ __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size);
// Check if the target allocation and file both have the same number of bytes
// for an Element
@@ -2717,19 +2627,16 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
if (!alloc)
return false;
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64 ".", __FUNCTION__,
- *alloc->address.get());
+ LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64 ".", __FUNCTION__,
+ *alloc->address.get());
// JIT all the allocation details
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr)) {
- if (log)
- log->Printf("%s - couldn't JIT allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't JIT allocation details.", __FUNCTION__);
return false;
}
}
@@ -2743,14 +2650,14 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Check we can create writable file
FileSpec file_spec(path);
FileSystem::Instance().Resolve(file_spec);
- File file;
- FileSystem::Instance().Open(file, file_spec,
- File::eOpenOptionWrite |
- File::eOpenOptionCanCreate |
- File::eOpenOptionTruncate);
+ auto file = FileSystem::Instance().Open(
+ file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionTruncate);
if (!file) {
- strm.Printf("Error: Failed to open '%s' for writing", path);
+ std::string error = llvm::toString(file.takeError());
+ strm.Printf("Error: Failed to open '%s' for writing: %s", path,
+ error.c_str());
strm.EOL();
return false;
}
@@ -2779,11 +2686,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Write the file header
size_t num_bytes = sizeof(AllocationDetails::FileHeader);
- if (log)
- log->Printf("%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__,
- (uint64_t)num_bytes);
+ LLDB_LOGF(log, "%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__,
+ (uint64_t)num_bytes);
- Status err = file.Write(&head, num_bytes);
+ Status err = file.get()->Write(&head, num_bytes);
if (!err.Success()) {
strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
strm.EOL();
@@ -2805,11 +2711,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Write headers for allocation element type to file
num_bytes = element_header_size;
- if (log)
- log->Printf("%s - writing element headers, 0x%" PRIx64 " bytes.",
- __FUNCTION__, (uint64_t)num_bytes);
+ LLDB_LOGF(log, "%s - writing element headers, 0x%" PRIx64 " bytes.",
+ __FUNCTION__, (uint64_t)num_bytes);
- err = file.Write(element_header_buffer.get(), num_bytes);
+ err = file.get()->Write(element_header_buffer.get(), num_bytes);
if (!err.Success()) {
strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
strm.EOL();
@@ -2818,11 +2723,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Write allocation data to file
num_bytes = static_cast<size_t>(*alloc->size.get());
- if (log)
- log->Printf("%s - writing 0x%" PRIx64 " bytes", __FUNCTION__,
- (uint64_t)num_bytes);
+ LLDB_LOGF(log, "%s - writing 0x%" PRIx64 " bytes", __FUNCTION__,
+ (uint64_t)num_bytes);
- err = file.Write(buffer.get(), num_bytes);
+ err = file.get()->Write(buffer.get(), num_bytes);
if (!err.Success()) {
strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
strm.EOL();
@@ -2894,17 +2798,17 @@ bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) {
addr_t addr = debug_present->GetLoadAddress(&target);
GetProcess()->WriteMemory(addr, &flag, sizeof(flag), err);
if (err.Success()) {
- if (log)
- log->Printf("%s - debugger present flag set on debugee.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - debugger present flag set on debugee.",
+ __FUNCTION__);
m_debuggerPresentFlagged = true;
} else if (log) {
- log->Printf("%s - error writing debugger present flags '%s' ",
- __FUNCTION__, err.AsCString());
+ LLDB_LOGF(log, "%s - error writing debugger present flags '%s' ",
+ __FUNCTION__, err.AsCString());
}
} else if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"%s - error writing debugger present flags - symbol not found",
__FUNCTION__);
}
@@ -3004,8 +2908,7 @@ bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines,
return false;
}
- if (log)
- log->Printf("Found RenderScript reduction '%s'", spec[2].str().c_str());
+ LLDB_LOGF(log, "Found RenderScript reduction '%s'", spec[2].str().c_str());
m_reductions.push_back(RSReductionDescriptor(this, sig, accum_data_size,
spec[2], spec[3], spec[4],
@@ -3082,10 +2985,8 @@ bool RSModuleDescriptor::ParseRSInfo() {
{
const llvm::StringRef raw_rs_info((const char *)buffer->GetBytes());
raw_rs_info.split(info_lines, '\n');
- if (log)
- log->Printf("'.rs.info symbol for '%s':\n%s",
- m_module->GetFileSpec().GetCString(),
- raw_rs_info.str().c_str());
+ LLDB_LOGF(log, "'.rs.info symbol for '%s':\n%s",
+ m_module->GetFileSpec().GetCString(), raw_rs_info.str().c_str());
}
enum {
@@ -3153,9 +3054,8 @@ bool RSModuleDescriptor::ParseRSInfo() {
success = ParseVersionInfo(line, n_lines);
break;
default: {
- if (log)
- log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__,
- line->str().c_str());
+ LLDB_LOGF(log, "%s - skipping .rs.info field '%s'", __FUNCTION__,
+ line->str().c_str());
continue;
}
}
@@ -3276,15 +3176,13 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
if (!alloc)
return false; // FindAllocByID() will print error message for us here
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__,
- *alloc->address.get());
+ LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__,
+ *alloc->address.get());
// Check we have information about the allocation, if not calculate it
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
// JIT all the allocation information
if (!RefreshAllocation(alloc, frame_ptr)) {
@@ -3313,9 +3211,8 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
const uint32_t data_size = *alloc->element.datum_size.get();
- if (log)
- log->Printf("%s - element size %" PRIu32 " bytes, including padding",
- __FUNCTION__, data_size);
+ LLDB_LOGF(log, "%s - element size %" PRIu32 " bytes, including padding",
+ __FUNCTION__, data_size);
// Allocate a buffer to copy data into
std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
@@ -3340,10 +3237,10 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
const uint32_t size = *alloc->size.get(); // Size of whole allocation
const uint32_t padding =
alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
- if (log)
- log->Printf("%s - stride %" PRIu32 " bytes, size %" PRIu32
- " bytes, padding %" PRIu32,
- __FUNCTION__, stride, size, padding);
+ LLDB_LOGF(log,
+ "%s - stride %" PRIu32 " bytes, size %" PRIu32
+ " bytes, padding %" PRIu32,
+ __FUNCTION__, stride, size, padding);
// Find dimensions used to index loops, so need to be non-zero
uint32_t dim_x = alloc->dimension.get()->dim_1;
@@ -3395,8 +3292,7 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
*alloc->data_ptr.get() + offset);
if (written < 0 || written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error in snprintf().", __FUNCTION__);
continue;
}
@@ -3573,17 +3469,16 @@ void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) {
for (const auto &module : m_rsmodules)
BreakOnModuleKernels(module);
- if (log)
- log->Printf("%s(True) - breakpoints set on all currently loaded kernels.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "%s(True) - breakpoints set on all currently loaded kernels.",
+ __FUNCTION__);
} else if (!do_break &&
m_breakAllKernels) // Breakpoints won't be set on any new kernels.
{
m_breakAllKernels = false;
- if (log)
- log->Printf("%s(False) - breakpoints no longer automatically set.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s(False) - breakpoints no longer automatically set.",
+ __FUNCTION__);
}
}
@@ -3595,8 +3490,8 @@ RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) {
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp) {
- if (log)
- log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
+ __FUNCTION__);
return nullptr;
}
@@ -3610,9 +3505,8 @@ RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) {
Status err;
target.AddNameToBreakpoint(bp, "RenderScriptKernel", err);
if (err.Fail() && log)
- if (log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
return bp;
}
@@ -3624,8 +3518,8 @@ RenderScriptRuntime::CreateReductionBreakpoint(ConstString name,
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp) {
- if (log)
- log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
+ __FUNCTION__);
return nullptr;
}
@@ -3640,8 +3534,8 @@ RenderScriptRuntime::CreateReductionBreakpoint(ConstString name,
Status err;
target.AddNameToBreakpoint(bp, "RenderScriptReduction", err);
if (err.Fail() && log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
return bp;
}
@@ -3663,9 +3557,8 @@ bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp,
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
var_sp, err));
if (!err.Success()) {
- if (log)
- log->Printf("%s - error, couldn't find '%s' in frame", __FUNCTION__,
- var_name);
+ LLDB_LOGF(log, "%s - error, couldn't find '%s' in frame", __FUNCTION__,
+ var_name);
return false;
}
@@ -3673,9 +3566,8 @@ bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp,
bool success = false;
val = value_sp->GetValueAsUnsigned(0, &success);
if (!success) {
- if (log)
- log->Printf("%s - error, couldn't parse '%s' as an uint32_t.",
- __FUNCTION__, var_name);
+ LLDB_LOGF(log, "%s - error, couldn't parse '%s' as an uint32_t.",
+ __FUNCTION__, var_name);
return false;
}
@@ -3695,8 +3587,7 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!thread_ptr) {
- if (log)
- log->Printf("%s - Error, No thread pointer", __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error, No thread pointer", __FUNCTION__);
return false;
}
@@ -3718,17 +3609,15 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
if (!func_name)
continue;
- if (log)
- log->Printf("%s - Inspecting function '%s'", __FUNCTION__,
- func_name.GetCString());
+ LLDB_LOGF(log, "%s - Inspecting function '%s'", __FUNCTION__,
+ func_name.GetCString());
// Check if function name has .expand suffix
if (!func_name.GetStringRef().endswith(".expand"))
continue;
- if (log)
- log->Printf("%s - Found .expand function '%s'", __FUNCTION__,
- func_name.GetCString());
+ LLDB_LOGF(log, "%s - Found .expand function '%s'", __FUNCTION__,
+ func_name.GetCString());
// Get values for variables in .expand frame that tell us the current
// kernel invocation
@@ -3770,9 +3659,8 @@ bool RenderScriptRuntime::KernelBreakpointHit(void *baton,
// Coordinate we want to stop on
RSCoordinate target_coord = *static_cast<RSCoordinate *>(baton);
- if (log)
- log->Printf("%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__, break_id,
- target_coord.x, target_coord.y, target_coord.z);
+ LLDB_LOGF(log, "%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__,
+ break_id, target_coord.x, target_coord.y, target_coord.z);
// Select current thread
ExecutionContext context(ctx->exe_ctx_ref);
@@ -3782,22 +3670,19 @@ bool RenderScriptRuntime::KernelBreakpointHit(void *baton,
// Find current kernel invocation from .expand frame variables
RSCoordinate current_coord{};
if (!GetKernelCoordinate(current_coord, thread_ptr)) {
- if (log)
- log->Printf("%s - Error, couldn't select .expand stack frame",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error, couldn't select .expand stack frame",
+ __FUNCTION__);
return false;
}
- if (log)
- log->Printf("%s - " FMT_COORD, __FUNCTION__, current_coord.x,
- current_coord.y, current_coord.z);
+ LLDB_LOGF(log, "%s - " FMT_COORD, __FUNCTION__, current_coord.x,
+ current_coord.y, current_coord.z);
// Check if the current kernel invocation coordinate matches our target
// coordinate
if (target_coord == current_coord) {
- if (log)
- log->Printf("%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x,
- current_coord.y, current_coord.z);
+ LLDB_LOGF(log, "%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x,
+ current_coord.y, current_coord.z);
BreakpointSP breakpoint_sp =
context.GetTargetPtr()->GetBreakpointByID(break_id);
@@ -3865,8 +3750,8 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name,
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp) {
- if (log)
- log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
+ __FUNCTION__);
return nullptr;
}
@@ -3880,8 +3765,8 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name,
Status err;
target.AddNameToBreakpoint(bp, name.GetCString(), err);
if (err.Fail() && log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
// ask the breakpoint to resolve itself
bp->ResolveBreakpoint();
return bp;
@@ -3964,9 +3849,8 @@ RenderScriptRuntime::CreateAllocation(addr_t address) {
auto it = m_allocations.begin();
while (it != m_allocations.end()) {
if (*((*it)->address) == address) {
- if (log)
- log->Printf("%s - Removing allocation id: %d, address: 0x%" PRIx64,
- __FUNCTION__, (*it)->id, address);
+ LLDB_LOGF(log, "%s - Removing allocation id: %d, address: 0x%" PRIx64,
+ __FUNCTION__, (*it)->id, address);
it = m_allocations.erase(it);
} else {
@@ -3988,9 +3872,8 @@ bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr,
Address resolved;
// RenderScript module
if (!target.GetSectionLoadList().ResolveLoadAddress(kernel_addr, resolved)) {
- if (log)
- log->Printf("%s: unable to resolve 0x%" PRIx64 " to a loaded symbol",
- __FUNCTION__, kernel_addr);
+ LLDB_LOGF(log, "%s: unable to resolve 0x%" PRIx64 " to a loaded symbol",
+ __FUNCTION__, kernel_addr);
return false;
}
@@ -4000,9 +3883,8 @@ bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr,
name = sym->GetName();
assert(IsRenderScriptModule(resolved.CalculateSymbolContextModule()));
- if (log)
- log->Printf("%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__,
- kernel_addr, name.GetCString());
+ LLDB_LOGF(log, "%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__,
+ kernel_addr, name.GetCString());
return true;
}
@@ -4256,13 +4138,12 @@ public:
// Matching a comma separated list of known words is fairly
// straightforward with PCRE, but we're using ERE, so we end up with a
// little ugliness...
- RegularExpression::Match match(/* max_matches */ 5);
RegularExpression match_type_list(
llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$"));
assert(match_type_list.IsValid());
- if (!match_type_list.Execute(option_val, &match)) {
+ if (!match_type_list.Execute(option_val)) {
err_str.PutCString(
"a comma-separated list of kernel types is required");
return false;
@@ -4696,32 +4577,36 @@ public:
return false;
}
- Stream *output_strm = nullptr;
- StreamFile outfile_stream;
+ Stream *output_stream_p = nullptr;
+ std::unique_ptr<Stream> output_stream_storage;
+
const FileSpec &outfile_spec =
m_options.m_outfile; // Dump allocation to file instead
if (outfile_spec) {
// Open output file
std::string path = outfile_spec.GetPath();
- auto error = FileSystem::Instance().Open(
- outfile_stream.GetFile(), outfile_spec,
- File::eOpenOptionWrite | File::eOpenOptionCanCreate);
- if (error.Success()) {
- output_strm = &outfile_stream;
+ auto file = FileSystem::Instance().Open(
+ outfile_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate);
+ if (file) {
+ output_stream_storage =
+ std::make_unique<StreamFile>(std::move(file.get()));
+ output_stream_p = output_stream_storage.get();
result.GetOutputStream().Printf("Results written to '%s'",
path.c_str());
result.GetOutputStream().EOL();
} else {
- result.AppendErrorWithFormat("Couldn't open file '%s'", path.c_str());
+ std::string error = llvm::toString(file.takeError());
+ result.AppendErrorWithFormat("Couldn't open file '%s': %s",
+ path.c_str(), error.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
} else
- output_strm = &result.GetOutputStream();
+ output_stream_p = &result.GetOutputStream();
- assert(output_strm != nullptr);
+ assert(output_stream_p != nullptr);
bool dumped =
- runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id);
+ runtime->DumpAllocation(*output_stream_p, m_exe_ctx.GetFramePtr(), id);
if (dumped)
result.SetStatus(eReturnStatusSuccessFinishResult);
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 3923221d4302..c3740ba55a11 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -67,8 +67,8 @@ public:
void Dump(Stream *s) const override {}
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
@@ -117,8 +117,8 @@ public:
void Dump(Stream *s) const override {}
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
@@ -262,8 +262,8 @@ public:
void Dump(Stream *s) const override {}
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
index 4725e8c5b0eb..a6d225d2fbd8 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
@@ -93,9 +93,8 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
assert(orig && "CallInst has no called function");
llvm::FunctionType *orig_type = orig->getFunctionType();
auto name = orig->getName();
- if (log)
- log->Printf("%s - cloning to StructRet function for '%s'", __FUNCTION__,
- name.str().c_str());
+ LLDB_LOGF(log, "%s - cloning to StructRet function for '%s'", __FUNCTION__,
+ name.str().c_str());
unsigned num_params = orig_type->getNumParams();
std::vector<llvm::Type *> new_params{num_params + 1, nullptr};
@@ -113,9 +112,9 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
if (!return_type_ptr_type)
return nullptr;
- if (log)
- log->Printf("%s - return type pointer type for StructRet clone @ '0x%p':\n",
- __FUNCTION__, (void *)return_type_ptr_type);
+ LLDB_LOGF(log,
+ "%s - return type pointer type for StructRet clone @ '0x%p':\n",
+ __FUNCTION__, (void *)return_type_ptr_type);
// put the sret pointer argument in place at the beginning of the
// argument list.
params.emplace(params.begin(), return_type_ptr_type);
diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index d489eaf11115..de17d986a860 100644
--- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -16,7 +16,19 @@ using namespace lldb_private;
using namespace lldb_private::breakpad;
namespace {
-enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack, CFI, Init };
+enum class Token {
+ Unknown,
+ Module,
+ Info,
+ CodeID,
+ File,
+ Func,
+ Public,
+ Stack,
+ CFI,
+ Init,
+ Win,
+};
}
template<typename T>
@@ -33,6 +45,7 @@ template <> Token stringTo<Token>(llvm::StringRef Str) {
.Case("STACK", Token::Stack)
.Case("CFI", Token::CFI)
.Case("INIT", Token::Init)
+ .Case("WIN", Token::Win)
.Default(Token::Unknown);
}
@@ -127,6 +140,8 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
switch (Tok) {
case Token::CFI:
return Record::StackCFI;
+ case Token::Win:
+ return Record::StackWin;
default:
return llvm::None;
}
@@ -134,13 +149,13 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
case Token::Unknown:
// Optimistically assume that any unrecognised token means this is a line
// record, those don't have a special keyword and start directly with a
- // hex number. CODE_ID should never be at the start of a line, but if it
- // is, it can be treated the same way as a garbled line record.
+ // hex number.
return Record::Line;
case Token::CodeID:
case Token::CFI:
case Token::Init:
+ case Token::Win:
// These should never appear at the start of a valid record.
return llvm::None;
}
@@ -390,6 +405,81 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
return OS << " " << R.UnwindRules;
}
+llvm::Optional<StackWinRecord> StackWinRecord::parse(llvm::StringRef Line) {
+ // STACK WIN type rva code_size prologue_size epilogue_size parameter_size
+ // saved_register_size local_size max_stack_size has_program_string
+ // program_string_OR_allocates_base_pointer
+
+ if (consume<Token>(Line) != Token::Stack)
+ return llvm::None;
+ if (consume<Token>(Line) != Token::Win)
+ return llvm::None;
+
+ llvm::StringRef Str;
+ uint8_t Type;
+ std::tie(Str, Line) = getToken(Line);
+ // Right now we only support the "FrameData" frame type.
+ if (!to_integer(Str, Type) || FrameType(Type) != FrameType::FrameData)
+ return llvm::None;
+
+ lldb::addr_t RVA;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, RVA, 16))
+ return llvm::None;
+
+ lldb::addr_t CodeSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, CodeSize, 16))
+ return llvm::None;
+
+ // Skip fields which we aren't using right now.
+ std::tie(Str, Line) = getToken(Line); // prologue_size
+ std::tie(Str, Line) = getToken(Line); // epilogue_size
+
+ lldb::addr_t ParameterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, ParameterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t SavedRegisterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, SavedRegisterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t LocalSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, LocalSize, 16))
+ return llvm::None;
+
+ std::tie(Str, Line) = getToken(Line); // max_stack_size
+
+ uint8_t HasProgramString;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, HasProgramString))
+ return llvm::None;
+ // FrameData records should always have a program string.
+ if (!HasProgramString)
+ return llvm::None;
+
+ return StackWinRecord(RVA, CodeSize, ParameterSize, SavedRegisterSize,
+ LocalSize, Line.trim());
+}
+
+bool breakpad::operator==(const StackWinRecord &L, const StackWinRecord &R) {
+ return L.RVA == R.RVA && L.CodeSize == R.CodeSize &&
+ L.ParameterSize == R.ParameterSize &&
+ L.SavedRegisterSize == R.SavedRegisterSize &&
+ L.LocalSize == R.LocalSize && L.ProgramString == R.ProgramString;
+}
+
+llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
+ const StackWinRecord &R) {
+ return OS << llvm::formatv(
+ "STACK WIN 4 {0:x-} {1:x-} ? ? {2} {3} {4} ? 1 {5}", R.RVA,
+ R.CodeSize, R.ParameterSize, R.SavedRegisterSize, R.LocalSize,
+ R.ProgramString);
+}
+
llvm::StringRef breakpad::toString(Record::Kind K) {
switch (K) {
case Record::Module:
@@ -406,6 +496,8 @@ llvm::StringRef breakpad::toString(Record::Kind K) {
return "PUBLIC";
case Record::StackCFI:
return "STACK CFI";
+ case Record::StackWin:
+ return "STACK WIN";
}
llvm_unreachable("Unknown record kind!");
}
diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
index 5d5cdb319c10..27bef975125d 100644
--- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
+++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
@@ -20,7 +20,7 @@ namespace breakpad {
class Record {
public:
- enum Kind { Module, Info, File, Func, Line, Public, StackCFI };
+ enum Kind { Module, Info, File, Func, Line, Public, StackCFI, StackWin };
/// Attempt to guess the kind of the record present in the argument without
/// doing a full parse. The returned kind will always be correct for valid
@@ -157,6 +157,29 @@ public:
bool operator==(const StackCFIRecord &L, const StackCFIRecord &R);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R);
+class StackWinRecord : public Record {
+public:
+ static llvm::Optional<StackWinRecord> parse(llvm::StringRef Line);
+
+ StackWinRecord(lldb::addr_t RVA, lldb::addr_t CodeSize,
+ lldb::addr_t ParameterSize, lldb::addr_t SavedRegisterSize,
+ lldb::addr_t LocalSize, llvm::StringRef ProgramString)
+ : Record(StackWin), RVA(RVA), CodeSize(CodeSize),
+ ParameterSize(ParameterSize), SavedRegisterSize(SavedRegisterSize),
+ LocalSize(LocalSize), ProgramString(ProgramString) {}
+
+ enum class FrameType : uint8_t { FPO = 0, FrameData = 4 };
+ lldb::addr_t RVA;
+ lldb::addr_t CodeSize;
+ lldb::addr_t ParameterSize;
+ lldb::addr_t SavedRegisterSize;
+ lldb::addr_t LocalSize;
+ llvm::StringRef ProgramString;
+};
+
+bool operator==(const StackWinRecord &L, const StackWinRecord &R);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R);
+
} // namespace breakpad
} // namespace lldb_private
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index 60dd9f9cecf0..3b9e0e2092a9 100644
--- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -42,6 +42,8 @@ llvm::Optional<Header> Header::parse(llvm::StringRef text) {
return Header{ArchSpec(triple), std::move(uuid)};
}
+char ObjectFileBreakpad::ID;
+
void ObjectFileBreakpad::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
@@ -125,7 +127,7 @@ Symtab *ObjectFileBreakpad::GetSymtab() {
void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
- m_sections_up = llvm::make_unique<SectionList>();
+ m_sections_up = std::make_unique<SectionList>();
llvm::Optional<Record::Kind> current_section;
offset_t section_start;
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index e8885e0cc898..cb4bba01fb71 100644
--- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -48,6 +48,13 @@ public:
uint32_t GetPluginVersion() override { return 1; }
+ // LLVM RTTI support
+ static char ID;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || ObjectFile::isA(ClassID);
+ }
+ static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
// ObjectFile Protocol.
bool ParseHeader() override;
@@ -78,8 +85,6 @@ public:
UUID GetUUID() override { return m_uuid; }
- FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); }
-
uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
Type CalculateType() override { return eTypeDebugInfo; }
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index d62afa34bbe8..3f8502548fc2 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -18,6 +18,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/LZMA.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/SectionLoadList.h"
@@ -29,12 +30,13 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
-
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/CRC.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MipsABIFlags.h"
@@ -80,41 +82,6 @@ const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
-// LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants
-#define NT_PRSTATUS 1
-#define NT_PRFPREG 2
-#define NT_PRPSINFO 3
-#define NT_TASKSTRUCT 4
-#define NT_AUXV 6
-#define NT_SIGINFO 0x53494749
-#define NT_FILE 0x46494c45
-#define NT_PRXFPREG 0x46e62b7f
-#define NT_PPC_VMX 0x100
-#define NT_PPC_SPE 0x101
-#define NT_PPC_VSX 0x102
-#define NT_386_TLS 0x200
-#define NT_386_IOPERM 0x201
-#define NT_X86_XSTATE 0x202
-#define NT_S390_HIGH_GPRS 0x300
-#define NT_S390_TIMER 0x301
-#define NT_S390_TODCMP 0x302
-#define NT_S390_TODPREG 0x303
-#define NT_S390_CTRS 0x304
-#define NT_S390_PREFIX 0x305
-#define NT_S390_LAST_BREAK 0x306
-#define NT_S390_SYSTEM_CALL 0x307
-#define NT_S390_TDB 0x308
-#define NT_S390_VXRS_LOW 0x309
-#define NT_S390_VXRS_HIGH 0x30a
-#define NT_ARM_VFP 0x400
-#define NT_ARM_TLS 0x401
-#define NT_ARM_HW_BREAK 0x402
-#define NT_ARM_HW_WATCH 0x403
-#define NT_ARM_SYSTEM_CALL 0x404
-#define NT_METAG_CBUF 0x500
-#define NT_METAG_RPIPE 0x501
-#define NT_METAG_TLS 0x502
-
//===----------------------------------------------------------------------===//
/// \class ELFRelocation
/// Generic wrapper for ELFRel and ELFRela.
@@ -264,8 +231,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
if (cstr == nullptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
- if (log)
- log->Printf("Failed to parse note name lacking nul terminator");
+ LLDB_LOGF(log, "Failed to parse note name lacking nul terminator");
return false;
}
@@ -333,6 +299,8 @@ static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
return LLDB_INVALID_CPUTYPE;
}
+char ObjectFileELF::ID;
+
// Arbitrary constant used as UUID prefix for core files.
const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
@@ -429,67 +397,9 @@ bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
return false;
}
-/*
- * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
- *
- * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
- * code or tables extracted from it, as desired without restriction.
- */
-static uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) {
- static const uint32_t g_crc32_tab[] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
- const uint8_t *p = (const uint8_t *)buf;
-
- crc = crc ^ ~0U;
- while (size--)
- crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
- return crc ^ ~0U;
-}
-
-static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) {
- return calc_crc32(0U, buf, size);
+static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) {
+ return llvm::crc32(
+ init, llvm::makeArrayRef(data.GetDataStart(), data.GetByteSize()));
}
uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
@@ -509,8 +419,7 @@ uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
break;
}
- core_notes_crc = calc_crc32(core_notes_crc, segment_data.GetDataStart(),
- segment_data.GetByteSize());
+ core_notes_crc = calc_crc32(core_notes_crc, segment_data);
}
}
@@ -608,10 +517,9 @@ size_t ObjectFileELF::GetModuleSpecifications(
llvm::Triple::OSType spec_ostype =
spec.GetArchitecture().GetTriple().getOS();
- if (log)
- log->Printf("ObjectFileELF::%s file '%s' module OSABI: %s",
- __FUNCTION__, file.GetPath().c_str(),
- OSABIAsCString(header.e_ident[EI_OSABI]));
+ LLDB_LOGF(log, "ObjectFileELF::%s file '%s' module OSABI: %s",
+ __FUNCTION__, file.GetPath().c_str(),
+ OSABIAsCString(header.e_ident[EI_OSABI]));
// SetArchitecture should have set the vendor to unknown
vendor = spec.GetArchitecture().GetTriple().getVendor();
@@ -623,10 +531,10 @@ size_t ObjectFileELF::GetModuleSpecifications(
GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
assert(spec_ostype == ostype);
if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
- if (log)
- log->Printf("ObjectFileELF::%s file '%s' set ELF module OS type "
- "from ELF header OSABI.",
- __FUNCTION__, file.GetPath().c_str());
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s file '%s' set ELF module OS type "
+ "from ELF header OSABI.",
+ __FUNCTION__, file.GetPath().c_str());
}
data_sp = MapFileData(file, -1, file_offset);
@@ -652,12 +560,12 @@ size_t ObjectFileELF::GetModuleSpecifications(
llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple();
- if (log)
- log->Printf("ObjectFileELF::%s file '%s' module set to triple: %s "
- "(architecture %s)",
- __FUNCTION__, file.GetPath().c_str(),
- spec_triple.getTriple().c_str(),
- spec.GetArchitecture().GetArchitectureName());
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s file '%s' module set to triple: %s "
+ "(architecture %s)",
+ __FUNCTION__, file.GetPath().c_str(),
+ spec_triple.getTriple().c_str(),
+ spec.GetArchitecture().GetArchitectureName());
if (!uuid.IsValid()) {
uint32_t core_notes_crc = 0;
@@ -682,8 +590,7 @@ size_t ObjectFileELF::GetModuleSpecifications(
core_notes_crc =
CalculateELFNotesSegmentsCRC32(program_headers, data);
} else {
- gnu_debuglink_crc = calc_gnu_debuglink_crc32(
- data.GetDataStart(), data.GetByteSize());
+ gnu_debuglink_crc = calc_crc32(0, data);
}
}
using u32le = llvm::support::ulittle32_t;
@@ -721,27 +628,16 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
DataBufferSP &data_sp, lldb::offset_t data_offset,
const FileSpec *file, lldb::offset_t file_offset,
lldb::offset_t length)
- : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
- m_program_headers(), m_section_headers(), m_dynamic_symbols(),
- m_filespec_up(), m_entry_point_address(), m_arch_spec() {
+ : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
if (file)
m_file = *file;
- ::memset(&m_header, 0, sizeof(m_header));
}
ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
DataBufferSP &header_data_sp,
const lldb::ProcessSP &process_sp,
addr_t header_addr)
- : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
- m_program_headers(), m_section_headers(), m_dynamic_symbols(),
- m_filespec_up(), m_entry_point_address(), m_arch_spec() {
- ::memset(&m_header, 0, sizeof(m_header));
-}
-
-ObjectFileELF::~ObjectFileELF() {}
+ : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
bool ObjectFileELF::IsExecutable() const {
return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
@@ -872,8 +768,7 @@ UUID ObjectFileELF::GetUUID() {
}
} else {
if (!m_gnu_debuglink_crc)
- m_gnu_debuglink_crc = calc_gnu_debuglink_crc32(m_data.GetDataStart(),
- m_data.GetByteSize());
+ m_gnu_debuglink_crc = calc_crc32(0, m_data);
if (m_gnu_debuglink_crc) {
// Use 4 bytes of crc from the .gnu_debuglink section.
u32le data(m_gnu_debuglink_crc);
@@ -885,14 +780,10 @@ UUID ObjectFileELF::GetUUID() {
return m_uuid;
}
-lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() {
- FileSpecList file_spec_list;
-
- if (!m_gnu_debuglink_file.empty()) {
- FileSpec file_spec(m_gnu_debuglink_file);
- file_spec_list.Append(file_spec);
- }
- return file_spec_list;
+llvm::Optional<FileSpec> ObjectFileELF::GetDebugLink() {
+ if (m_gnu_debuglink_file.empty())
+ return llvm::None;
+ return FileSpec(m_gnu_debuglink_file);
}
uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
@@ -1120,9 +1011,8 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
return error;
}
- if (log)
- log->Printf("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
- __FUNCTION__, note.n_name.c_str(), note.n_type);
+ LLDB_LOGF(log, "ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
+ __FUNCTION__, note.n_name.c_str(), note.n_type);
// Process FreeBSD ELF notes.
if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
@@ -1147,11 +1037,11 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().setOSName(os_name);
arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
- ".%" PRIu32,
- __FUNCTION__, version_major, version_minor,
- static_cast<uint32_t>(version_info % 1000));
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
+ ".%" PRIu32,
+ __FUNCTION__, version_major, version_minor,
+ static_cast<uint32_t>(version_info % 1000));
}
// Process GNU ELF notes.
else if (note.n_name == LLDB_NT_OWNER_GNU) {
@@ -1172,12 +1062,11 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
arch_spec.GetTriple().setVendor(
llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf(
- "ObjectFileELF::%s detected Linux, min version %" PRIu32
- ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[1], version_info[2],
- version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected Linux, min version %" PRIu32
+ ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
// FIXME we have the minimal version number, we could be propagating
// that. version_info[1] = OS Major, version_info[2] = OS Minor,
// version_info[3] = Revision.
@@ -1186,30 +1075,28 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
arch_spec.GetTriple().setVendor(
llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf("ObjectFileELF::%s detected Hurd (unsupported), min "
- "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[1], version_info[2],
- version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected Hurd (unsupported), min "
+ "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
break;
case LLDB_NT_GNU_ABI_OS_SOLARIS:
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris);
arch_spec.GetTriple().setVendor(
llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf(
- "ObjectFileELF::%s detected Solaris, min version %" PRIu32
- ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[1], version_info[2],
- version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected Solaris, min version %" PRIu32
+ ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
break;
default:
- if (log)
- log->Printf(
- "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
- ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[0], version_info[1],
- version_info[2], version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
+ ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[0], version_info[1],
+ version_info[2], version_info[3]);
break;
}
}
@@ -1618,9 +1505,8 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
section_size) == section_size)) {
Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
if (error.Fail()) {
- if (log)
- log->Printf("ObjectFileELF::%s ELF note processing failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "ObjectFileELF::%s ELF note processing failed: %s",
+ __FUNCTION__, error.AsCString());
}
}
}
@@ -1790,6 +1676,8 @@ class VMAddressProvider {
VMMap Segments = VMMap(Alloc);
VMMap Sections = VMMap(Alloc);
lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+ size_t SegmentCount = 0;
+ std::string SegmentName;
VMRange GetVMRange(const ELFSectionHeader &H) {
addr_t Address = H.sh_addr;
@@ -1804,18 +1692,23 @@ class VMAddressProvider {
}
public:
- VMAddressProvider(ObjectFile::Type Type) : ObjectType(Type) {}
+ VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName)
+ : ObjectType(Type), SegmentName(SegmentName) {}
+
+ std::string GetNextSegmentName() const {
+ return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str();
+ }
llvm::Optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) {
if (H.p_memsz == 0) {
- LLDB_LOG(Log,
- "Ignoring zero-sized PT_LOAD segment. Corrupt object file?");
+ LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?",
+ SegmentName);
return llvm::None;
}
if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) {
- LLDB_LOG(Log,
- "Ignoring overlapping PT_LOAD segment. Corrupt object file?");
+ LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?",
+ SegmentName);
return llvm::None;
}
return VMRange(H.p_vaddr, H.p_memsz);
@@ -1850,6 +1743,7 @@ public:
void AddSegment(const VMRange &Range, SectionSP Seg) {
Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
+ ++SegmentCount;
}
void AddSection(SectionAddressInfo Info, SectionSP Sect) {
@@ -1867,29 +1761,32 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
- m_sections_up = llvm::make_unique<SectionList>();
- VMAddressProvider address_provider(GetType());
+ m_sections_up = std::make_unique<SectionList>();
+ VMAddressProvider regular_provider(GetType(), "PT_LOAD");
+ VMAddressProvider tls_provider(GetType(), "PT_TLS");
- size_t LoadID = 0;
for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
const ELFProgramHeader &PHdr = EnumPHdr.value();
- if (PHdr.p_type != PT_LOAD)
+ if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS)
continue;
- auto InfoOr = address_provider.GetAddressInfo(PHdr);
+ VMAddressProvider &provider =
+ PHdr.p_type == PT_TLS ? tls_provider : regular_provider;
+ auto InfoOr = provider.GetAddressInfo(PHdr);
if (!InfoOr)
continue;
- ConstString Name(("PT_LOAD[" + llvm::Twine(LoadID++) + "]").str());
uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1));
SectionSP Segment = std::make_shared<Section>(
- GetModule(), this, SegmentID(EnumPHdr.index()), Name,
- eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(),
- PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0);
+ GetModule(), this, SegmentID(EnumPHdr.index()),
+ ConstString(provider.GetNextSegmentName()), eSectionTypeContainer,
+ InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset,
+ PHdr.p_filesz, Log2Align, /*flags*/ 0);
Segment->SetPermissions(GetPermissions(PHdr));
+ Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS);
m_sections_up->AddSection(Segment);
- address_provider.AddSegment(*InfoOr, std::move(Segment));
+ provider.AddSegment(*InfoOr, std::move(Segment));
}
ParseSectionHeaders();
@@ -1904,7 +1801,9 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
const uint64_t file_size =
header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
- auto InfoOr = address_provider.GetAddressInfo(header);
+ VMAddressProvider &provider =
+ header.sh_flags & SHF_TLS ? tls_provider : regular_provider;
+ auto InfoOr = provider.GetAddressInfo(header);
if (!InfoOr)
continue;
@@ -1935,13 +1834,77 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS);
(InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up)
.AddSection(section_sp);
- address_provider.AddSection(std::move(*InfoOr), std::move(section_sp));
+ provider.AddSection(std::move(*InfoOr), std::move(section_sp));
}
// For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
// unified section list.
if (GetType() != eTypeDebugInfo)
unified_section_list = *m_sections_up;
+
+ // If there's a .gnu_debugdata section, we'll try to read the .symtab that's
+ // embedded in there and replace the one in the original object file (if any).
+ // If there's none in the orignal object file, we add it to it.
+ if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) {
+ if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) {
+ if (SectionSP symtab_section_sp =
+ gdd_objfile_section_list->FindSectionByType(
+ eSectionTypeELFSymbolTable, true)) {
+ SectionSP module_section_sp = unified_section_list.FindSectionByType(
+ eSectionTypeELFSymbolTable, true);
+ if (module_section_sp)
+ unified_section_list.ReplaceSection(module_section_sp->GetID(),
+ symtab_section_sp);
+ else
+ unified_section_list.AddSection(symtab_section_sp);
+ }
+ }
+ }
+}
+
+std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
+ if (m_gnu_debug_data_object_file != nullptr)
+ return m_gnu_debug_data_object_file;
+
+ SectionSP section =
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"));
+ if (!section)
+ return nullptr;
+
+ if (!lldb_private::lzma::isAvailable()) {
+ GetModule()->ReportWarning(
+ "No LZMA support found for reading .gnu_debugdata section");
+ return nullptr;
+ }
+
+ // Uncompress the data
+ DataExtractor data;
+ section->GetSectionData(data);
+ llvm::SmallVector<uint8_t, 0> uncompressedData;
+ auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData);
+ if (err) {
+ GetModule()->ReportWarning(
+ "An error occurred while decompression the section %s: %s",
+ section->GetName().AsCString(), llvm::toString(std::move(err)).c_str());
+ return nullptr;
+ }
+
+ // Construct ObjectFileELF object from decompressed buffer
+ DataBufferSP gdd_data_buf(
+ new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
+ auto fspec = GetFileSpec().CopyByAppendingPathComponent(
+ llvm::StringRef("gnu_debugdata"));
+ m_gnu_debug_data_object_file.reset(new ObjectFileELF(
+ GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
+
+ // This line is essential; otherwise a breakpoint can be set but not hit.
+ m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo);
+
+ ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture();
+ if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec))
+ return m_gnu_debug_data_object_file;
+
+ return nullptr;
}
// Find the arm/aarch64 mapping symbol character in the given symbol name.
@@ -2246,8 +2209,6 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
bool is_global = symbol.getBinding() == STB_GLOBAL;
uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
- bool is_mangled = (symbol_name[0] == '_' && symbol_name[1] == 'Z');
-
llvm::StringRef symbol_ref(symbol_name);
// Symbol names may contain @VERSION suffixes. Find those and strip them
@@ -2255,7 +2216,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
size_t version_pos = symbol_ref.find('@');
bool has_suffix = version_pos != llvm::StringRef::npos;
llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
- Mangled mangled(ConstString(symbol_bare), is_mangled);
+ Mangled mangled(symbol_bare);
// Now append the suffix back to mangled and unmangled names. Only do it if
// the demangling was successful (string is not empty).
@@ -2486,14 +2447,11 @@ static unsigned ParsePLTRelocations(
break;
const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
- bool is_mangled =
- symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
uint64_t plt_index = plt_offset + i * plt_entsize;
Symbol jump_symbol(
i + start_id, // Symbol table index
symbol_name, // symbol name.
- is_mangled, // is the symbol name mangled?
eSymbolTypeTrampoline, // Type of this symbol
false, // Is this globally visible?
false, // Is this symbol debug info?
@@ -2654,7 +2612,7 @@ unsigned ObjectFileELF::ApplyRelocations(
((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) {
Log *log =
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
- log->Printf("Failed to apply debug info relocations");
+ LLDB_LOGF(log, "Failed to apply debug info relocations");
break;
}
uint32_t truncated_addr = (value & 0xFFFFFFFF);
@@ -2749,19 +2707,29 @@ Symtab *ObjectFileELF::GetSymtab() {
// while the reverse is not necessarily true.
Section *symtab =
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
- if (!symtab) {
- // The symtab section is non-allocable and can be stripped, so if it
- // doesn't exist then use the dynsym section which should always be
- // there.
- symtab =
- section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
- .get();
- }
if (symtab) {
m_symtab_up.reset(new Symtab(symtab->GetObjectFile()));
symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
}
+ // The symtab section is non-allocable and can be stripped, while the
+ // .dynsym section which should always be always be there. To support the
+ // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
+ // section, nomatter if .symtab was already parsed or not. This is because
+ // minidebuginfo normally removes the .symtab symbols which have their
+ // matching .dynsym counterparts.
+ if (!symtab ||
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+ .get();
+ if (dynsym) {
+ if (!m_symtab_up)
+ m_symtab_up.reset(new Symtab(dynsym->GetObjectFile()));
+ symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
+ }
+ }
+
// DT_JMPREL
// If present, this entry's d_ptr member holds the address of
// relocation
@@ -2803,6 +2771,50 @@ Symtab *ObjectFileELF::GetSymtab() {
if (m_symtab_up == nullptr)
m_symtab_up.reset(new Symtab(this));
+ // In the event that there's no symbol entry for the entry point we'll
+ // artifically create one. We delegate to the symtab object the figuring
+ // out of the proper size, this will usually make it span til the next
+ // symbol it finds in the section. This means that if there are missing
+ // symbols the entry point might span beyond its function definition.
+ // We're fine with this as it doesn't make it worse than not having a
+ // symbol entry at all.
+ if (CalculateType() == eTypeExecutable) {
+ ArchSpec arch = GetArchitecture();
+ auto entry_point_addr = GetEntryPointAddress();
+ bool is_valid_entry_point =
+ entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
+ addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
+ if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
+ entry_point_file_addr)) {
+ uint64_t symbol_id = m_symtab_up->GetNumSymbols();
+ Symbol symbol(symbol_id,
+ GetNextSyntheticSymbolName().GetCString(), // Symbol name.
+ eSymbolTypeCode, // Type of this symbol.
+ true, // Is this globally visible?
+ false, // Is this symbol debug info?
+ false, // Is this symbol a trampoline?
+ true, // Is this symbol artificial?
+ entry_point_addr.GetSection(), // Section where this
+ // symbol is defined.
+ 0, // Offset in section or symbol value.
+ 0, // Size.
+ false, // Size is valid.
+ false, // Contains linker annotations?
+ 0); // Symbol flags.
+ m_symtab_up->AddSymbol(symbol);
+ // When the entry point is arm thumb we need to explicitly set its
+ // class address to reflect that. This is important because expression
+ // evaluation relies on correctly setting a breakpoint at this
+ // address.
+ if (arch.GetMachine() == llvm::Triple::arm &&
+ (entry_point_file_addr & 1))
+ m_address_class_map[entry_point_file_addr ^ 1] =
+ AddressClass::eCodeAlternateISA;
+ else
+ m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
+ }
+ }
+
m_symtab_up->CalculateSymbolSizes();
}
@@ -2881,7 +2893,6 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
Symbol eh_symbol(
symbol_id, // Symbol table index.
symbol_name, // Symbol name.
- false, // Is the symbol name mangled?
eSymbolTypeCode, // Type of this symbol.
true, // Is this globally visible?
false, // Is this symbol debug info?
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index b63a5d14d4f5..3b273896cb59 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -56,8 +56,6 @@ struct ELFNote {
/// the ObjectFile protocol.
class ObjectFileELF : public lldb_private::ObjectFile {
public:
- ~ObjectFileELF() override;
-
// Static Functions
static void Initialize();
@@ -91,6 +89,13 @@ public:
uint32_t GetPluginVersion() override;
+ // LLVM RTTI support
+ static char ID;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || ObjectFile::isA(ClassID);
+ }
+ static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
// ObjectFile Protocol.
bool ParseHeader() override;
@@ -117,7 +122,9 @@ public:
lldb_private::UUID GetUUID() override;
- lldb_private::FileSpecList GetDebugSymbolFilePaths() override;
+ /// Return the contents of the .gnu_debuglink section, if the object file
+ /// contains it.
+ llvm::Optional<lldb_private::FileSpec> GetDebugLink();
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
@@ -190,7 +197,7 @@ private:
/// ELF .gnu_debuglink file and crc data if available.
std::string m_gnu_debuglink_file;
- uint32_t m_gnu_debuglink_crc;
+ uint32_t m_gnu_debuglink_crc = 0;
/// Collection of program headers.
ProgramHeaderColl m_program_headers;
@@ -201,6 +208,10 @@ private:
/// Collection of symbols from the dynamic table.
DynamicSymbolColl m_dynamic_symbols;
+ /// Object file parsed from .gnu_debugdata section (\sa
+ /// GetGnuDebugDataObjectFile())
+ std::shared_ptr<ObjectFileELF> m_gnu_debug_data_object_file;
+
/// List of file specifications corresponding to the modules (shared
/// libraries) on which this object file depends.
mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up;
@@ -376,6 +387,14 @@ private:
lldb_private::UUID &uuid);
bool AnySegmentHasPhysicalAddress();
+
+ /// Takes the .gnu_debugdata and returns the decompressed object file that is
+ /// stored within that section.
+ ///
+ /// \returns either the decompressed object file stored within the
+ /// .gnu_debugdata section or \c nullptr if an error occured or if there's no
+ /// section with that name.
+ std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile();
};
#endif // liblldb_ObjectFileELF_h_
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index eaf973da3835..c55b96d9110b 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -39,6 +39,8 @@
using namespace lldb;
using namespace lldb_private;
+char ObjectFileJIT::ID;
+
void ObjectFileJIT::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index 99241126cd1a..c992683cfc3c 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -46,6 +46,13 @@ public:
lldb::offset_t length,
lldb_private::ModuleSpecList &specs);
+ // LLVM RTTI support
+ static char ID;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || ObjectFile::isA(ClassID);
+ }
+ static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
// Member Functions
bool ParseHeader() override;
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index c1fe0cc8ddda..b777a5319104 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -120,10 +120,10 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
return nullptr;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
- if (log)
- log->Printf("OperatingSystemPython::GetDynamicRegisterInfo() fetching "
- "thread register definitions from python for pid %" PRIu64,
- m_process->GetID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::GetDynamicRegisterInfo() fetching "
+ "thread register definitions from python for pid %" PRIu64,
+ m_process->GetID());
StructuredData::DictionarySP dictionary =
m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp);
@@ -169,12 +169,12 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
api_lock.try_lock();
auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
- if (log)
- log->Printf("OperatingSystemPython::UpdateThreadList() fetching thread "
- "data from python for pid %" PRIu64,
- m_process->GetID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::UpdateThreadList() fetching thread "
+ "data from python for pid %" PRIu64,
+ m_process->GetID());
- // The threads that are in "new_thread_list" upon entry are the threads from
+ // The threads that are in "core_thread_list" upon entry are the threads from
// the lldb_private::Process subclass, no memory threads will be in this
// list.
StructuredData::ArraySP threads_list =
@@ -190,7 +190,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
if (log) {
StreamString strm;
threads_list->Dump(strm);
- log->Printf("threads_list = %s", strm.GetData());
+ LLDB_LOGF(log, "threads_list = %s", strm.GetData());
}
const uint32_t num_threads = threads_list->GetSize();
@@ -316,21 +316,21 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
if (reg_data_addr != LLDB_INVALID_ADDRESS) {
// The registers data is in contiguous memory, just create the register
// context using the address provided
- if (log)
- log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
- "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64
- ") creating memory register context",
- thread->GetID(), thread->GetProtocolID(), reg_data_addr);
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64
+ ") creating memory register context",
+ thread->GetID(), thread->GetProtocolID(), reg_data_addr);
reg_ctx_sp = std::make_shared<RegisterContextMemory>(
*thread, 0, *GetDynamicRegisterInfo(), reg_data_addr);
} else {
// No register data address is provided, query the python plug-in to let it
// make up the data as it sees fit
- if (log)
- log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
- "= 0x%" PRIx64 ", 0x%" PRIx64
- ") fetching register data from python",
- thread->GetID(), thread->GetProtocolID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ", 0x%" PRIx64
+ ") fetching register data from python",
+ thread->GetID(), thread->GetProtocolID());
StructuredData::StringSP reg_context_data =
m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp,
@@ -351,10 +351,10 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
// if we still have no register data, fallback on a dummy context to avoid
// crashing
if (!reg_ctx_sp) {
- if (log)
- log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
- "= 0x%" PRIx64 ") forcing a dummy register context",
- thread->GetID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ") forcing a dummy register context",
+ thread->GetID());
reg_ctx_sp = std::make_shared<RegisterContextDummy>(
*thread, 0, target.GetArchitecture().GetAddressByteSize());
}
@@ -375,10 +375,10 @@ lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid,
addr_t context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64
- ", context = 0x%" PRIx64 ") fetching register data from python",
- tid, context);
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateThread (tid = 0x%" PRIx64
+ ", 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
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index d10557596ff8..b12e21deb459 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -27,11 +27,11 @@
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/ScopeExit.h"
using namespace lldb;
using namespace lldb_private;
@@ -276,8 +276,7 @@ PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,
} else
command.Printf("rsync %s %s %s:%s", GetRSyncOpts(), src_path.c_str(),
GetHostname(), dst_path.c_str());
- if (log)
- log->Printf("[PutFile] Running command: %s\n", command.GetData());
+ LLDB_LOGF(log, "[PutFile] Running command: %s\n", command.GetData());
int retcode;
Host::RunShellCommand(command.GetData(), nullptr, &retcode, nullptr,
nullptr, std::chrono::minutes(1));
@@ -334,8 +333,7 @@ lldb_private::Status PlatformPOSIX::GetFile(
command.Printf("rsync %s %s:%s %s", GetRSyncOpts(),
m_remote_platform_sp->GetHostname(), src_path.c_str(),
dst_path.c_str());
- if (log)
- log->Printf("[GetFile] Running command: %s\n", command.GetData());
+ LLDB_LOGF(log, "[GetFile] Running command: %s\n", command.GetData());
int retcode;
Host::RunShellCommand(command.GetData(), nullptr, &retcode, nullptr,
nullptr, std::chrono::minutes(1));
@@ -348,8 +346,7 @@ lldb_private::Status PlatformPOSIX::GetFile(
// read/write, read/write, read/write, ...
// close src
// close dst
- if (log)
- log->Printf("[GetFile] Using block by block transfer....\n");
+ LLDB_LOGF(log, "[GetFile] Using block by block transfer....\n");
Status error;
user_id_t fd_src = OpenFile(source, File::eOpenOptionRead,
lldb::eFilePermissionsFileDefault, error);
@@ -515,24 +512,21 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
error = debugger.GetTargetList().CreateTarget(
debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
target = new_target_sp.get();
- if (log)
- log->Printf("PlatformPOSIX::%s created new target", __FUNCTION__);
+ LLDB_LOGF(log, "PlatformPOSIX::%s created new target", __FUNCTION__);
} else {
error.Clear();
- if (log)
- log->Printf("PlatformPOSIX::%s target already existed, setting target",
- __FUNCTION__);
+ LLDB_LOGF(log, "PlatformPOSIX::%s target already existed, setting target",
+ __FUNCTION__);
}
if (target && error.Success()) {
debugger.GetTargetList().SetSelectedTarget(target);
if (log) {
ModuleSP exe_module_sp = target->GetExecutableModule();
- log->Printf("PlatformPOSIX::%s set selected target to %p %s",
- __FUNCTION__, (void *)target,
- exe_module_sp
- ? exe_module_sp->GetFileSpec().GetPath().c_str()
- : "<null>");
+ LLDB_LOGF(log, "PlatformPOSIX::%s set selected target to %p %s",
+ __FUNCTION__, (void *)target,
+ exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
+ : "<null>");
}
process_sp =
@@ -804,12 +798,13 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
"for path: %s", utility_error.AsCString());
return LLDB_INVALID_IMAGE_TOKEN;
}
-
+
// Make sure we deallocate the input string memory:
- CleanUp path_cleanup([process, path_addr] {
- process->DeallocateMemory(path_addr);
+ auto path_cleanup = llvm::make_scope_exit([process, path_addr] {
+ // Deallocate the buffer.
+ process->DeallocateMemory(path_addr);
});
-
+
process->WriteMemory(path_addr, path.c_str(), path_len, utility_error);
if (utility_error.Fail()) {
error.SetErrorStringWithFormat("dlopen error: could not write path string:"
@@ -830,21 +825,24 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
}
// Make sure we deallocate the result structure memory
- CleanUp return_cleanup([process, return_addr] {
- process->DeallocateMemory(return_addr);
+ auto return_cleanup = llvm::make_scope_exit([process, return_addr] {
+ // Deallocate the buffer
+ process->DeallocateMemory(return_addr);
});
-
+
// This will be the address of the storage for paths, if we are using them,
// or nullptr to signal we aren't.
lldb::addr_t path_array_addr = 0x0;
- llvm::Optional<CleanUp> path_array_cleanup;
+ llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
+ path_array_cleanup;
// This is the address to a buffer large enough to hold the largest path
// conjoined with the library name we're passing in. This is a convenience
// to avoid having to call malloc in the dlopen function.
lldb::addr_t buffer_addr = 0x0;
- llvm::Optional<CleanUp> buffer_cleanup;
-
+ llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
+ buffer_cleanup;
+
// Set the values into our args and write them to the target:
if (paths != nullptr) {
// First insert the paths into the target. This is expected to be a
@@ -877,8 +875,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
}
// Make sure we deallocate the paths array.
- path_array_cleanup.emplace([process, path_array_addr] {
- process->DeallocateMemory(path_array_addr);
+ path_array_cleanup.emplace([process, path_array_addr]() {
+ // Deallocate the path array.
+ process->DeallocateMemory(path_array_addr);
});
process->WriteMemory(path_array_addr, path_array.data(),
@@ -904,8 +903,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
}
// Make sure we deallocate the buffer memory:
- buffer_cleanup.emplace([process, buffer_addr] {
- process->DeallocateMemory(buffer_addr);
+ buffer_cleanup.emplace([process, buffer_addr]() {
+ // Deallocate the buffer.
+ process->DeallocateMemory(buffer_addr);
});
}
@@ -930,10 +930,11 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
// Make sure we clean up the args structure. We can't reuse it because the
// Platform lives longer than the process and the Platforms don't get a
// signal to clean up cached data when a process goes away.
- CleanUp args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] {
- do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr);
- });
-
+ auto args_cleanup =
+ llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] {
+ do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr);
+ });
+
// Now run the caller:
EvaluateExpressionOptions options;
options.SetExecutionPolicy(eExecutionPolicyAlways);
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 9c52b59e2b06..1e62ddfe94fd 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -169,21 +169,21 @@ bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec,
const auto module_path = module_file_spec.GetPath(false);
if (!m_gdb_client.GetModuleInfo(module_file_spec, arch, module_spec)) {
- if (log)
- log->Printf(
- "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
- __FUNCTION__, module_path.c_str(),
- arch.GetTriple().getTriple().c_str());
+ LLDB_LOGF(
+ log,
+ "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
+ __FUNCTION__, module_path.c_str(),
+ arch.GetTriple().getTriple().c_str());
return false;
}
if (log) {
StreamString stream;
module_spec.Dump(stream);
- log->Printf(
- "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
- __FUNCTION__, module_path.c_str(), arch.GetTriple().getTriple().c_str(),
- stream.GetData());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
+ __FUNCTION__, module_path.c_str(),
+ arch.GetTriple().getTriple().c_str(), stream.GetData());
}
return true;
@@ -253,9 +253,9 @@ FileSpec PlatformRemoteGDBServer::GetRemoteWorkingDirectory() {
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
FileSpec working_dir;
if (m_gdb_client.GetWorkingDir(working_dir) && log)
- log->Printf(
- "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
- working_dir.GetCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
+ working_dir.GetCString());
return working_dir;
} else {
return Platform::GetRemoteWorkingDirectory();
@@ -268,9 +268,8 @@ bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory(
// Clear the working directory it case it doesn't get set correctly. This
// will for use to re-read it
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
- working_dir.GetCString());
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
+ working_dir.GetCString());
return m_gdb_client.SetWorkingDir(working_dir) == 0;
} else
return Platform::SetRemoteWorkingDirectory(working_dir);
@@ -370,8 +369,7 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
Status error;
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() called", __FUNCTION__);
auto num_file_actions = launch_info.GetNumFileActions();
for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) {
@@ -408,10 +406,10 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
const char *arch_triple = arch_spec.GetTriple().str().c_str();
m_gdb_client.SendLaunchArchPacket(arch_triple);
- if (log)
- log->Printf(
- "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
- __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
+ LLDB_LOGF(
+ log,
+ "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
+ __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
int arg_packet_err;
{
@@ -427,22 +425,21 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
const auto pid = m_gdb_client.GetCurrentProcessID(false);
if (pid != LLDB_INVALID_PROCESS_ID) {
launch_info.SetProcessID(pid);
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() pid %" PRIu64
- " launched successfully",
- __FUNCTION__, pid);
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::%s() pid %" PRIu64
+ " launched successfully",
+ __FUNCTION__, pid);
} else {
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() launch succeeded but we "
- "didn't get a valid process id back!",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::%s() launch succeeded but we "
+ "didn't get a valid process id back!",
+ __FUNCTION__);
error.SetErrorString("failed to get PID");
}
} else {
error.SetErrorString(error_str.c_str());
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() launch failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() launch failed: %s",
+ __FUNCTION__, error.AsCString());
}
} else {
error.SetErrorStringWithFormat("'A' packet returned an error: %i",
@@ -600,11 +597,10 @@ Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec,
uint32_t mode) {
Status error = m_gdb_client.MakeDirectory(file_spec, mode);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
- "error = %u (%s)",
- file_spec.GetCString(), mode, error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
+ "error = %u (%s)",
+ file_spec.GetCString(), mode, error.GetError(), error.AsCString());
return error;
}
@@ -612,11 +608,11 @@ Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions) {
Status error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
- "file_permissions=%o) error = %u (%s)",
- file_spec.GetCString(), file_permissions, error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
+ "file_permissions=%o) error = %u (%s)",
+ file_spec.GetCString(), file_permissions, error.GetError(),
+ error.AsCString());
return error;
}
@@ -624,16 +620,17 @@ Status PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions) {
Status error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
- "file_permissions=%o) error = %u (%s)",
- file_spec.GetCString(), file_permissions, error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
+ "file_permissions=%o) error = %u (%s)",
+ file_spec.GetCString(), file_permissions, error.GetError(),
+ error.AsCString());
return error;
}
lldb::user_id_t PlatformRemoteGDBServer::OpenFile(const FileSpec &file_spec,
- uint32_t flags, uint32_t mode,
+ File::OpenOptions flags,
+ uint32_t mode,
Status &error) {
return m_gdb_client.OpenFile(file_spec, flags, mode, error);
}
@@ -671,20 +668,19 @@ Status PlatformRemoteGDBServer::CreateSymlink(
{
Status error = m_gdb_client.CreateSymlink(src, dst);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
- "error = %u (%s)",
- src.GetCString(), dst.GetCString(), error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
+ "error = %u (%s)",
+ src.GetCString(), dst.GetCString(), error.GetError(),
+ error.AsCString());
return error;
}
Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) {
Status error = m_gdb_client.Unlink(file_spec);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
- file_spec.GetCString(), error.GetError(), error.AsCString());
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
+ file_spec.GetCString(), error.GetError(), error.AsCString());
return error;
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index c774daa8ab73..13edcbab9f59 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -113,7 +113,7 @@ public:
Status SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions) override;
- lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
uint32_t mode, Status &error) override;
bool CloseFile(lldb::user_id_t fd, Status &error) override;
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
index 3ec410fe7d76..f70ef97a2bc5 100644
--- a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -254,9 +254,8 @@ CreatePosixSpawnFileAction(const FileAction &action,
case FileAction::eFileActionNone:
default:
- if (log)
- log->Printf("%s(): unsupported file action %u", __FUNCTION__,
- action.GetAction());
+ LLDB_LOGF(log, "%s(): unsupported file action %u", __FUNCTION__,
+ action.GetAction());
break;
}
@@ -288,8 +287,7 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
int error_code;
if ((error_code = ::posix_spawnattr_init(&attr)) != 0) {
- if (log)
- log->Printf("::posix_spawnattr_init(&attr) failed");
+ LLDB_LOGF(log, "::posix_spawnattr_init(&attr) failed");
error.SetError(error_code, eErrorTypePOSIX);
return error;
}
@@ -378,10 +376,10 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
error = CreatePosixSpawnFileAction(*action, &file_actions);
if (!error.Success()) {
- if (log)
- log->Printf("%s(): error converting FileAction to posix_spawn "
- "file action: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "%s(): error converting FileAction to posix_spawn "
+ "file action: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
}
@@ -416,10 +414,10 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
if (actual_cpu_type) {
*actual_cpu_type = GetCPUTypeForLocalProcess(*pid);
- if (log)
- log->Printf("%s(): cpu type for launched process pid=%i: "
- "cpu_type=0x%8.8x",
- __FUNCTION__, *pid, *actual_cpu_type);
+ LLDB_LOGF(log,
+ "%s(): cpu type for launched process pid=%i: "
+ "cpu_type=0x%8.8x",
+ __FUNCTION__, *pid, *actual_cpu_type);
}
return error;
@@ -477,23 +475,21 @@ Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
char resolved_path[PATH_MAX];
resolved_path[0] = '\0';
- if (log)
- log->Printf("%s(): attempting to resolve given binary path: \"%s\"",
- __FUNCTION__, given_path);
+ LLDB_LOGF(log, "%s(): attempting to resolve given binary path: \"%s\"",
+ __FUNCTION__, given_path);
// If we fail to resolve the path to our executable, then just use what we
// were given and hope for the best
if (!ResolveExecutablePath(given_path, resolved_path,
sizeof(resolved_path))) {
- if (log)
- log->Printf("%s(): failed to resolve binary path, using "
- "what was given verbatim and hoping for the best",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "%s(): failed to resolve binary path, using "
+ "what was given verbatim and hoping for the best",
+ __FUNCTION__);
::strncpy(resolved_path, given_path, sizeof(resolved_path));
} else {
- if (log)
- log->Printf("%s(): resolved given binary path to: \"%s\"", __FUNCTION__,
- resolved_path);
+ LLDB_LOGF(log, "%s(): resolved given binary path to: \"%s\"", __FUNCTION__,
+ resolved_path);
}
char launch_err_str[PATH_MAX];
diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp
index 70ad6736a748..073ad64b300c 100644
--- a/source/Plugins/Process/Darwin/MachException.cpp
+++ b/source/Plugins/Process/Darwin/MachException.cpp
@@ -67,10 +67,11 @@ extern "C" kern_return_t catch_mach_exception_raise_state(
// TODO change to LIBLLDB_LOG_EXCEPTION
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log) {
- log->Printf("::%s(exc_port = 0x%4.4x, exc_type = %d (%s), "
- "exc_data = 0x%llx, exc_data_count = %d)",
- __FUNCTION__, exc_port, exc_type, MachException::Name(exc_type),
- (uint64_t)exc_data, exc_data_count);
+ LLDB_LOGF(log,
+ "::%s(exc_port = 0x%4.4x, exc_type = %d (%s), "
+ "exc_data = 0x%llx, exc_data_count = %d)",
+ __FUNCTION__, exc_port, exc_type, MachException::Name(exc_type),
+ (uint64_t)exc_data, exc_data_count);
}
return KERN_FAILURE;
}
@@ -83,13 +84,14 @@ extern "C" kern_return_t catch_mach_exception_raise_state_identity(
thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log) {
- log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
- "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] = "
- "{ 0x%llx, 0x%llx })",
- __FUNCTION__, exc_port, thread_port, task_port, exc_type,
- MachException::Name(exc_type), exc_data_count,
- (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
- (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
+ LLDB_LOGF(log,
+ "::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
+ "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] = "
+ "{ 0x%llx, 0x%llx })",
+ __FUNCTION__, exc_port, thread_port, task_port, exc_type,
+ MachException::Name(exc_type), exc_data_count,
+ (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
+ (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
}
return KERN_FAILURE;
@@ -102,13 +104,14 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
mach_msg_type_number_t exc_data_count) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log) {
- log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
- "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] "
- "= { 0x%llx, 0x%llx })",
- __FUNCTION__, exc_port, thread_port, task_port, exc_type,
- MachException::Name(exc_type), exc_data_count,
- (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
- (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
+ LLDB_LOGF(log,
+ "::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
+ "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] "
+ "= { 0x%llx, 0x%llx })",
+ __FUNCTION__, exc_port, thread_port, task_port, exc_type,
+ MachException::Name(exc_type), exc_data_count,
+ (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
+ (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
}
if (task_port == g_message->task_port) {
@@ -187,15 +190,16 @@ Status MachException::Message::Receive(mach_port_t port,
options & MACH_RCV_TIMEOUT ? timeout : 0;
if (log && ((options & MACH_RCV_TIMEOUT) == 0)) {
// Dump this log message if we have no timeout in case it never returns
- log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
- "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = 0, rcv_size = %llu, "
- "rcv_name = %#x, timeout = %u, notify = %#x)",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options,
- (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout,
- notify_port);
+ LLDB_LOGF(log,
+ "::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
+ "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = 0, rcv_size = %llu, "
+ "rcv_name = %#x, timeout = %u, notify = %#x)",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options,
+ (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout,
+ notify_port);
}
mach_msg_return_t mach_err =
@@ -213,15 +217,16 @@ Status MachException::Message::Receive(mach_port_t port,
// Dump any errors we get
if (error.Fail() && log) {
- log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
- "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = %u, rcv_size = %lu, rcv_name "
- "= %#x, timeout = %u, notify = %#x) failed: %s",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0,
- sizeof(exc_msg.data), port, mach_msg_timeout, notify_port,
- error.AsCString());
+ LLDB_LOGF(log,
+ "::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
+ "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = %u, rcv_size = %lu, rcv_name "
+ "= %#x, timeout = %u, notify = %#x) failed: %s",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0,
+ sizeof(exc_msg.data), port, mach_msg_timeout, notify_port,
+ error.AsCString());
}
return error;
}
@@ -264,10 +269,10 @@ bool MachException::Message::CatchExceptionRaise(task_t task) {
} else {
Log *log(
GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("MachException::Message::%s(): mach_exc_server "
- "returned zero...",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "MachException::Message::%s(): mach_exc_server "
+ "returned zero...",
+ __FUNCTION__);
}
g_message = NULL;
return success;
@@ -293,10 +298,10 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
auto mach_err = ::pid_for_task(state.task_port, &state_pid);
if (mach_err) {
error.SetError(mach_err, eErrorTypeMachKernel);
- if (log)
- log->Printf("MachException::Message::%s(): pid_for_task() "
- "failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "MachException::Message::%s(): pid_for_task() "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
}
@@ -309,25 +314,25 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
error.SetError(errno, eErrorTypePOSIX);
if (!error.Success()) {
- if (log)
- log->Printf("::ptrace(request = PT_THUPDATE, pid = "
- "0x%4.4x, tid = 0x%4.4x, signal = %i)",
- state_pid, state.thread_port, soft_signal);
+ LLDB_LOGF(log,
+ "::ptrace(request = PT_THUPDATE, pid = "
+ "0x%4.4x, tid = 0x%4.4x, signal = %i)",
+ state_pid, state.thread_port, soft_signal);
return error;
}
}
}
- if (log)
- log->Printf("::mach_msg ( msg->{bits = %#x, size = %u, remote_port "
- "= %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = %u, rcv_size = %u, rcv_name "
- "= %#x, timeout = %u, notify = %#x)",
- reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
- reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
- reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id,
- MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0,
- MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ LLDB_LOGF(log,
+ "::mach_msg ( msg->{bits = %#x, size = %u, remote_port "
+ "= %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = %u, rcv_size = %u, rcv_name "
+ "= %#x, timeout = %u, notify = %#x)",
+ reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
+ reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
+ reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id,
+ MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0,
+ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
auto mach_err =
::mach_msg(&reply_msg.hdr, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
@@ -342,12 +347,13 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
log->PutCString("::mach_msg() - send interrupted");
// TODO: keep retrying to reply???
} else if (state.task_port == inferior_task) {
- log->Printf("mach_msg(): returned an error when replying "
- "to a mach exception: error = %u (%s)",
- error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "mach_msg(): returned an error when replying "
+ "to a mach exception: error = %u (%s)",
+ error.GetError(), error.AsCString());
} else {
- log->Printf("::mach_msg() - failed (child of task): %u (%s)",
- error.GetError(), error.AsCString());
+ LLDB_LOGF(log, "::mach_msg() - failed (child of task): %u (%s)",
+ error.GetError(), error.AsCString());
}
}
@@ -377,9 +383,8 @@ Status MachException::PortInfo::Save(task_t task) {
Status error;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__,
- task);
+ LLDB_LOGF(log, "MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__,
+ task);
// Be careful to be able to have debugserver built on a newer OS than what it
// is currently running on by being able to start with all exceptions and
@@ -394,13 +399,15 @@ Status MachException::PortInfo::Save(task_t task) {
if (log) {
if (error.Success()) {
- log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = "
- "0x%x, maskCnt => %u, ports, behaviors, flavors)",
- task, mask, count);
+ LLDB_LOGF(log,
+ "::task_get_exception_ports(task = 0x%4.4x, mask = "
+ "0x%x, maskCnt => %u, ports, behaviors, flavors)",
+ task, mask, count);
} else {
- log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = 0x%x, "
- "maskCnt => %u, ports, behaviors, flavors) error: %u (%s)",
- task, mask, count, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "::task_get_exception_ports(task = 0x%4.4x, mask = 0x%x, "
+ "maskCnt => %u, ports, behaviors, flavors) error: %u (%s)",
+ task, mask, count, error.GetError(), error.AsCString());
}
}
@@ -413,15 +420,17 @@ Status MachException::PortInfo::Save(task_t task) {
error.SetError(mach_err, eErrorTypeMachKernel);
if (log) {
if (error.Success()) {
- log->Printf("::task_get_exception_ports(task = 0x%4.4x, "
- "mask = 0x%x, maskCnt => %u, ports, behaviors, "
- "flavors)",
- task, mask, count);
+ LLDB_LOGF(log,
+ "::task_get_exception_ports(task = 0x%4.4x, "
+ "mask = 0x%x, maskCnt => %u, ports, behaviors, "
+ "flavors)",
+ task, mask, count);
} else {
- log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = "
- "0x%x, maskCnt => %u, ports, behaviors, flavors) "
- "error: %u (%s)",
- task, mask, count, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "::task_get_exception_ports(task = 0x%4.4x, mask = "
+ "0x%x, maskCnt => %u, ports, behaviors, flavors) "
+ "error: %u (%s)",
+ task, mask, count, error.GetError(), error.AsCString());
}
}
}
@@ -437,8 +446,7 @@ Status MachException::PortInfo::Restore(task_t task) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("MachException::PortInfo::Restore(task = 0x%4.4x)", task);
+ LLDB_LOGF(log, "MachException::PortInfo::Restore(task = 0x%4.4x)", task);
uint32_t i = 0;
if (count > 0) {
@@ -449,17 +457,19 @@ Status MachException::PortInfo::Restore(task_t task) {
error.SetError(mach_err, eErrorTypeMachKernel);
if (log) {
if (error.Success()) {
- log->Printf("::task_set_exception_ports(task = 0x%4.4x, "
- "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
- "behavior = 0x%8.8x, new_flavor = 0x%8.8x)",
- task, masks[i], ports[i], behaviors[i], flavors[i]);
+ LLDB_LOGF(log,
+ "::task_set_exception_ports(task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x)",
+ task, masks[i], ports[i], behaviors[i], flavors[i]);
} else {
- log->Printf("::task_set_exception_ports(task = 0x%4.4x, "
- "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
- "behavior = 0x%8.8x, new_flavor = 0x%8.8x): "
- "error %u (%s)",
- task, masks[i], ports[i], behaviors[i], flavors[i],
- error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "::task_set_exception_ports(task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x): "
+ "error %u (%s)",
+ task, masks[i], ports[i], behaviors[i], flavors[i],
+ error.GetError(), error.AsCString());
}
}
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
index fe7de27e0ee6..18dbdda9a33b 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
@@ -75,19 +75,19 @@ Status NativeProcessProtocol::Launch(
// Handle launch failure.
if (!error.Success()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() failed to launch process: "
- "%s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() failed to launch process: "
+ "%s",
+ __FUNCTION__, error.AsCString());
return error;
}
// Handle failure to return a pid.
if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
- "pid was returned! Aborting.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() launch succeeded but no "
+ "pid was returned! Aborting.",
+ __FUNCTION__);
return error;
}
@@ -104,10 +104,10 @@ Status NativeProcessProtocol::Launch(
// NativeProcessDarwin instance.
error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
if (!error.Success()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
- " the launching of the process: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() aborting, failed to finalize"
+ " the launching of the process: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -120,9 +120,8 @@ Status NativeProcessProtocol::Attach(
lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
- pid);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
+ pid);
// Retrieve the architecture for the running process.
ArchSpec process_arch;
@@ -173,10 +172,10 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
error = StartExceptionThread();
if (!error.Success()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failure starting the "
- "mach exception port monitor thread: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failure starting the "
+ "mach exception port monitor thread: %s",
+ __FUNCTION__, error.AsCString());
// Terminate the inferior process. There's nothing meaningful we can do if
// we can't receive signals and exceptions. Since we launched the process,
@@ -195,33 +194,31 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
if (err == 0) {
// m_flags |= eMachProcessFlagsAttached;
- if (log)
- log->Printf("NativeProcessDarwin::%s(): successfully spawned "
- "process with pid %" PRIu64,
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): successfully spawned "
+ "process with pid %" PRIu64,
+ __FUNCTION__, m_pid);
} else {
error.SetErrorToErrno();
SetState(eStateExited);
- if (log)
- log->Printf("NativeProcessDarwin::%s(): error: failed to "
- "attach to spawned pid %" PRIu64 " (error=%d (%s))",
- __FUNCTION__, m_pid, (int)error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): error: failed to "
+ "attach to spawned pid %" PRIu64 " (error=%d (%s))",
+ __FUNCTION__, m_pid, (int)error.GetError(), error.AsCString());
return error;
}
}
- if (log)
- log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
+ __FUNCTION__, m_pid);
// Spawn a thread to reap our child inferior process...
error = StartWaitpidThread(main_loop);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
- "thread: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to start waitpid() "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
kill(SIGKILL, static_cast<::pid_t>(m_pid));
return error;
}
@@ -230,10 +227,10 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
// We failed to get the task for our process ID which is bad. Kill our
// process; otherwise, it will be stopped at the entry point and get
// reparented to someone else and never go away.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): could not get task port "
- "for process, sending SIGKILL and exiting: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): could not get task port "
+ "for process, sending SIGKILL and exiting: %s",
+ __FUNCTION__, error.AsCString());
kill(SIGKILL, static_cast<::pid_t>(m_pid));
return error;
}
@@ -278,18 +275,17 @@ void NativeProcessDarwin::ExceptionMessageReceived(
// the exception to our internal exception stack
m_exception_messages.push_back(message);
- if (log)
- log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
- __FUNCTION__, m_exception_messages.size());
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(): new queued message count: %lu",
+ __FUNCTION__, m_exception_messages.size());
}
void *NativeProcessDarwin::ExceptionThread(void *arg) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (!arg) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
- "thread, mandatory process arg was null",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): cannot run mach exception "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
return nullptr;
}
@@ -299,9 +295,8 @@ void *NativeProcessDarwin::ExceptionThread(void *arg) {
void *NativeProcessDarwin::DoExceptionThread() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
- __FUNCTION__, this);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(arg=%p) starting thread...",
+ __FUNCTION__, this);
pthread_setname_np("exception monitoring thread");
@@ -344,20 +339,20 @@ void *NativeProcessDarwin::DoExceptionThread() {
if (process->ProcessUsingSpringBoard()) {
// Request a renewal for every 60 seconds if we attached using SpringBoard.
watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
- if (log)
- log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
- "=> %p",
- pid, watchdog.get());
+ LLDB_LOGF(log,
+ "::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
+ "=> %p",
+ pid, watchdog.get());
if (watchdog.get()) {
::SBSWatchdogAssertionRenew(watchdog.get());
CFTimeInterval watchdogRenewalInterval =
::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
- if (log)
- log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
- "%g seconds",
- watchdog.get(), watchdogRenewalInterval);
+ LLDB_LOGF(log,
+ "::SBSWatchdogAssertionGetRenewalInterval(%p) => "
+ "%g seconds",
+ watchdog.get(), watchdogRenewalInterval);
if (watchdogRenewalInterval > 0.0) {
watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
if (watchdog_timeout > 3000) {
@@ -425,11 +420,11 @@ void *NativeProcessDarwin::DoExceptionThread() {
// If we have no task port we should exit this thread, as it implies
// the inferior went down.
if (!IsExceptionPortValid()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): the inferior "
- "exception port is no longer valid, "
- "canceling exception thread...",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): the inferior "
+ "exception port is no longer valid, "
+ "canceling exception thread...",
+ __FUNCTION__);
// Should we be setting a process state here?
break;
}
@@ -437,19 +432,19 @@ void *NativeProcessDarwin::DoExceptionThread() {
// Make sure the inferior task is still valid.
if (IsTaskValid()) {
// Task is still ok.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): interrupted, but "
- "the inferior task iss till valid, "
- "continuing...",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): interrupted, but "
+ "the inferior task iss till valid, "
+ "continuing...",
+ __FUNCTION__);
continue;
} else {
// The inferior task is no longer valid. Time to exit as the process
// has gone away.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): the inferior task "
- "has exited, and so will we...",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): the inferior task "
+ "has exited, and so will we...",
+ __FUNCTION__);
// Does this race at all with our waitpid()?
SetState(eStateExited);
break;
@@ -471,18 +466,18 @@ void *NativeProcessDarwin::DoExceptionThread() {
// our task is still valid.
if (IsTaskValid(task)) {
// Task is still ok.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): got a timeout, "
- "continuing...",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): got a timeout, "
+ "continuing...",
+ __FUNCTION__);
continue;
} else {
// The inferior task is no longer valid. Time to exit as the
// process has gone away.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): the inferior "
- "task has exited, and so will we...",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): the inferior "
+ "task has exited, and so will we...",
+ __FUNCTION__);
// Does this race at all with our waitpid()?
SetState(eStateExited);
break;
@@ -493,18 +488,17 @@ void *NativeProcessDarwin::DoExceptionThread() {
if (watchdog.get()) {
watchdog_elapsed += periodic_timeout;
if (watchdog_elapsed >= watchdog_timeout) {
- if (log)
- log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get());
+ LLDB_LOGF(log, "SBSWatchdogAssertionRenew(%p)", watchdog.get());
::SBSWatchdogAssertionRenew(watchdog.get());
watchdog_elapsed = 0;
}
}
#endif
} else {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): continuing after "
- "receiving an unexpected error: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): continuing after "
+ "receiving an unexpected error: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
// TODO: notify of error?
}
}
@@ -523,17 +517,15 @@ void *NativeProcessDarwin::DoExceptionThread() {
}
#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
- if (log)
- log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
- this);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
+ this);
return nullptr;
}
Status NativeProcessDarwin::StartExceptionThread() {
Status error;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__);
// Make sure we've looked up the inferior port.
TaskPortForProcessID(error);
@@ -554,11 +546,11 @@ Status NativeProcessDarwin::StartExceptionThread() {
&m_exception_port);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): mach_port_allocate("
- "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
- "&m_exception_port) failed: %u (%s)",
- __FUNCTION__, task_self, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): mach_port_allocate("
+ "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
+ "&m_exception_port) failed: %u (%s)",
+ __FUNCTION__, task_self, error.GetError(), error.AsCString());
return error;
}
@@ -567,23 +559,23 @@ Status NativeProcessDarwin::StartExceptionThread() {
task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right("
- "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
- "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
- "failed: %u (%s)",
- __FUNCTION__, task_self, m_exception_port, m_exception_port,
- error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): mach_port_insert_right("
+ "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
+ "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
+ "failed: %u (%s)",
+ __FUNCTION__, task_self, m_exception_port, m_exception_port,
+ error.GetError(), error.AsCString());
return error;
}
// Save the original state of the exception ports for our child process.
error = SaveExceptionPortInfo();
if (error.Fail() || (m_exc_port_info.mask == 0)) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
- "failed, cannot install exception handler: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
+ "failed, cannot install exception handler: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -593,14 +585,14 @@ Status NativeProcessDarwin::StartExceptionThread() {
EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("::task_set_exception_ports (task = 0x%4.4x, "
- "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
- "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
- "%u (%s)",
- m_task, m_exc_port_info.mask, m_exception_port,
- (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
- error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "::task_set_exception_ports (task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
+ "%u (%s)",
+ m_task, m_exc_port_info.mask, m_exception_port,
+ (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
+ error.GetError(), error.AsCString());
return error;
}
@@ -609,10 +601,10 @@ Status NativeProcessDarwin::StartExceptionThread() {
::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
error.SetError(pthread_err, eErrorTypePOSIX);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
- "exception-handling thread: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to create Mach "
+ "exception-handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
}
return error;
@@ -677,10 +669,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
- if (log)
- log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
- "messages.",
- __FUNCTION__, m_exception_messages.size());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): processing %lu exception "
+ "messages.",
+ __FUNCTION__, m_exception_messages.size());
if (m_exception_messages.empty()) {
// Not particularly useful...
@@ -733,18 +725,18 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
const bool force_update = true;
const task_t new_task = TaskPortForProcessID(error, force_update);
if (old_task != new_task) {
- if (log)
- log->Printf("exec: inferior task port changed "
- "from 0x%4.4x to 0x%4.4x",
- old_task, new_task);
+ LLDB_LOGF(log,
+ "exec: inferior task port changed "
+ "from 0x%4.4x to 0x%4.4x",
+ old_task, new_task);
}
}
} else {
- if (log)
- log->Printf("NativeProcessDarwin::%s() warning: "
- "failed to read all_image_infos."
- "infoArrayCount from 0x%8.8llx",
- __FUNCTION__, info_array_count_addr);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() warning: "
+ "failed to read all_image_infos."
+ "infoArrayCount from 0x%8.8llx",
+ __FUNCTION__, info_array_count_addr);
}
} else if ((m_sent_interrupt_signo != 0) &&
(signo == m_sent_interrupt_signo)) {
@@ -756,10 +748,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
if (m_did_exec) {
cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
if (m_cpu_type != process_cpu_type) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): arch changed from "
- "0x%8.8x to 0x%8.8x",
- __FUNCTION__, m_cpu_type, process_cpu_type);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): arch changed from "
+ "0x%8.8x to 0x%8.8x",
+ __FUNCTION__, m_cpu_type, process_cpu_type);
m_cpu_type = process_cpu_type;
// TODO figure out if we need to do something here.
// DNBArchProtocol::SetArchitecture (process_cpu_type);
@@ -772,10 +764,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
if (m_sent_interrupt_signo != 0) {
if (received_interrupt) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): process "
- "successfully interrupted with signal %i",
- __FUNCTION__, m_sent_interrupt_signo);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): process "
+ "successfully interrupted with signal %i",
+ __FUNCTION__, m_sent_interrupt_signo);
// Mark that we received the interrupt signal
m_sent_interrupt_signo = 0;
@@ -792,19 +784,19 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
// Only auto_resume if we stopped with _only_ the interrupt signal.
if (num_task_exceptions == 1) {
auto_resume = true;
- if (log)
- log->Printf("NativeProcessDarwin::%s(): auto "
- "resuming due to unhandled interrupt "
- "signal %i",
- __FUNCTION__, m_auto_resume_signo);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): auto "
+ "resuming due to unhandled interrupt "
+ "signal %i",
+ __FUNCTION__, m_auto_resume_signo);
}
m_auto_resume_signo = 0;
}
} else {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): didn't get signal "
- "%i after MachProcess::Interrupt()",
- __FUNCTION__, m_sent_interrupt_signo);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): didn't get signal "
+ "%i after MachProcess::Interrupt()",
+ __FUNCTION__, m_sent_interrupt_signo);
}
}
}
@@ -878,10 +870,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
const bool child_inherits = false;
error = m_waitpid_pipe.CreateNew(child_inherits);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
- "communication pipe: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to create waitpid "
+ "communication pipe: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -889,8 +881,8 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
// TODO make PipePOSIX derive from IOObject. This is goofy here.
const bool transfer_ownership = false;
- auto io_sp = IOObjectSP(
- new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership));
+ auto io_sp = IOObjectSP(new NativeFile(m_waitpid_pipe.GetReadFileDescriptor(),
+ transfer_ownership));
m_waitpid_reader_handle = main_loop.RegisterReadObject(
io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error);
@@ -899,10 +891,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
error.SetError(pthread_err, eErrorTypePOSIX);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
- "handling thread: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to create waitpid "
+ "handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
return error;
}
@@ -912,10 +904,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
void *NativeProcessDarwin::WaitpidThread(void *arg) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (!arg) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
- "thread, mandatory process arg was null",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): cannot run waitpid "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
return nullptr;
}
@@ -938,10 +930,10 @@ void *NativeProcessDarwin::DoWaitpidThread() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (m_pid == LLDB_INVALID_PROCESS_ID) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
- "not set, cannot waitpid on it",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): inferior process ID is "
+ "not set, cannot waitpid on it",
+ __FUNCTION__);
return nullptr;
}
@@ -962,41 +954,41 @@ void *NativeProcessDarwin::DoWaitpidThread() {
if (error.Fail()) {
if (error.GetError() == EINTR) {
// This is okay, we can keep going.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) interrupted, continuing",
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) interrupted, continuing",
+ __FUNCTION__, m_pid);
continue;
}
// This error is not okay, abort.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) aborting due to error: %u (%s)",
- __FUNCTION__, m_pid, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) aborting due to error: %u (%s)",
+ __FUNCTION__, m_pid, error.GetError(), error.AsCString());
break;
}
// Log the successful result.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) => %i, status = %i",
- __FUNCTION__, m_pid, child_pid, status);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) => %i, status = %i",
+ __FUNCTION__, m_pid, child_pid, status);
// Handle the result.
if (WIFSTOPPED(status)) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ") received a stop, continuing waitpid() loop",
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ") received a stop, continuing waitpid() loop",
+ __FUNCTION__, m_pid);
continue;
} else // if (WIFEXITED(status) || WIFSIGNALED(status))
{
- if (log)
- log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
- "waitpid thread is setting exit status for pid = "
- "%i to %i",
- __FUNCTION__, m_pid, child_pid, status);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(pid = %" PRIu64 "): "
+ "waitpid thread is setting exit status for pid = "
+ "%i to %i",
+ __FUNCTION__, m_pid, child_pid, status);
error = SendInferiorExitStatusToMainLoop(child_pid, status);
return nullptr;
@@ -1005,12 +997,11 @@ void *NativeProcessDarwin::DoWaitpidThread() {
// We should never exit as long as our child process is alive. If we get
// here, something completely unexpected went wrong and we should exit.
- if (log)
- log->Printf(
- "NativeProcessDarwin::%s(): internal error: waitpid thread "
- "exited out of its main loop in an unexpected way. pid = %" PRIu64
- ". Sending exit status of -1.",
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): internal error: waitpid thread "
+ "exited out of its main loop in an unexpected way. pid = %" PRIu64
+ ". Sending exit status of -1.",
+ __FUNCTION__, m_pid);
error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
return nullptr;
@@ -1026,11 +1017,11 @@ Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
// Send the pid.
error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
if (error.Fail() || (bytes_written < sizeof(pid))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to write "
- "waitpid exiting pid to the pipe. Client will not "
- "hear about inferior exit status!",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() - failed to write "
+ "waitpid exiting pid to the pipe. Client will not "
+ "hear about inferior exit status!",
+ __FUNCTION__);
return error;
}
@@ -1038,11 +1029,11 @@ Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
bytes_written = 0;
error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
if (error.Fail() || (bytes_written < sizeof(status))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to write "
- "waitpid exit result to the pipe. Client will not "
- "hear about inferior exit status!",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() - failed to write "
+ "waitpid exit result to the pipe. Client will not "
+ "hear about inferior exit status!",
+ __FUNCTION__);
}
return error;
}
@@ -1058,11 +1049,11 @@ Status NativeProcessDarwin::HandleWaitpidResult() {
size_t bytes_read = 0;
error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
if (error.Fail() || (bytes_read < sizeof(pid))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to read "
- "waitpid exiting pid from the pipe. Will notify "
- "as if parent process died with exit status -1.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() - failed to read "
+ "waitpid exiting pid from the pipe. Will notify "
+ "as if parent process died with exit status -1.",
+ __FUNCTION__);
SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
return error;
}
@@ -1071,21 +1062,21 @@ Status NativeProcessDarwin::HandleWaitpidResult() {
int status = -1;
error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
if (error.Fail() || (bytes_read < sizeof(status))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to read "
- "waitpid exit status from the pipe. Will notify "
- "as if parent process died with exit status -1.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() - failed to read "
+ "waitpid exit status from the pipe. Will notify "
+ "as if parent process died with exit status -1.",
+ __FUNCTION__);
SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
return error;
}
// Notify the monitor that our state has changed.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): main loop received waitpid "
- "exit status info: pid=%i (%s), status=%i",
- __FUNCTION__, pid,
- (pid == m_pid) ? "the inferior" : "not the inferior", status);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): main loop received waitpid "
+ "exit status info: pid=%i (%s), status=%i",
+ __FUNCTION__, pid,
+ (pid == m_pid) ? "the inferior" : "not the inferior", status);
SetExitStatus(WaitStatus::Decode(status), notify_status);
return error;
@@ -1096,10 +1087,10 @@ task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
if ((m_task == TASK_NULL) || force) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (m_pid == LLDB_INVALID_PROCESS_ID) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): cannot get task due "
- "to invalid pid",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): cannot get task due "
+ "to invalid pid",
+ __FUNCTION__);
return TASK_NULL;
}
@@ -1115,19 +1106,21 @@ task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
// Succeeded. Save and return it.
error.Clear();
m_task = task;
- log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
- "stub_port = 0x%4.4x, pid = %llu, &task) "
- "succeeded: inferior task port = 0x%4.4x",
- __FUNCTION__, task_self, m_pid, m_task);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): ::task_for_pid("
+ "stub_port = 0x%4.4x, pid = %llu, &task) "
+ "succeeded: inferior task port = 0x%4.4x",
+ __FUNCTION__, task_self, m_pid, m_task);
return m_task;
} else {
// Failed to get the task for the inferior process.
error.SetError(err, eErrorTypeMachKernel);
if (log) {
- log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
- "stub_port = 0x%4.4x, pid = %llu, &task) "
- "failed, err = 0x%8.8x (%s)",
- __FUNCTION__, task_self, m_pid, err, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): ::task_for_pid("
+ "stub_port = 0x%4.4x, pid = %llu, &task) "
+ "failed, err = 0x%8.8x (%s)",
+ __FUNCTION__, task_self, m_pid, err, error.AsCString());
}
}
@@ -1156,20 +1149,21 @@ Status NativeProcessDarwin::PrivateResume() {
if (log) {
if (m_auto_resume_signo)
- log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with "
- "unhandled interrupt signal %i)...",
- __FUNCTION__, m_task, m_auto_resume_signo);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): task 0x%x resuming (with "
+ "unhandled interrupt signal %i)...",
+ __FUNCTION__, m_task, m_auto_resume_signo);
else
- log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
- __FUNCTION__, m_task);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(): task 0x%x resuming...",
+ __FUNCTION__, m_task);
}
error = ReplyToAllExceptions();
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
- "reply to exceptions: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): aborting, failed to "
+ "reply to exceptions: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
// bool stepOverBreakInstruction = step;
@@ -1196,9 +1190,8 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
TaskPortForProcessID(error);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
- __FUNCTION__);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(): no task port, aborting",
+ __FUNCTION__);
return error;
}
@@ -1211,9 +1204,10 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
size_t index = 0;
for (auto &message : m_exception_messages) {
if (log) {
- log->Printf("NativeProcessDarwin::%s(): replying to exception "
- "%zu...",
- __FUNCTION__, index++);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): replying to exception "
+ "%zu...",
+ __FUNCTION__, index++);
}
int thread_reply_signal = 0;
@@ -1234,9 +1228,10 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
if (error.Fail() && log) {
// We log any error here, but we don't stop the exception response
// handling.
- log->Printf("NativeProcessDarwin::%s(): failed to reply to "
- "exception: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to reply to "
+ "exception: %s",
+ __FUNCTION__, error.AsCString());
error.Clear();
}
}
@@ -1253,10 +1248,10 @@ Status NativeProcessDarwin::ResumeTask() {
TaskPortForProcessID(error);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to get task port "
- "for process when attempting to resume: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to get task port "
+ "for process when attempting to resume: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
if (m_task == TASK_NULL) {
@@ -1265,20 +1260,20 @@ Status NativeProcessDarwin::ResumeTask() {
return error;
}
- if (log)
- log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
- "0x%4.4x",
- __FUNCTION__, m_task);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): requesting resume of task "
+ "0x%4.4x",
+ __FUNCTION__, m_task);
// Get the BasicInfo struct to verify that we're suspended before we try to
// resume the task.
struct task_basic_info task_info;
error = GetTaskBasicInfo(m_task, &task_info);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to get task "
- "BasicInfo when attempting to resume: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to get task "
+ "BasicInfo when attempting to resume: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -1289,16 +1284,16 @@ Status NativeProcessDarwin::ResumeTask() {
error.SetError(mach_err, eErrorTypeMachKernel);
if (log) {
if (error.Success())
- log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
+ LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x): success", m_task);
else
- log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
- error.AsCString());
+ LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x) error: %s", m_task,
+ error.AsCString());
}
} else {
- if (log)
- log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
- "already running",
- m_task);
+ LLDB_LOGF(log,
+ "::task_resume(target_task = 0x%4.4x): ignored, "
+ "already running",
+ m_task);
}
return error;
@@ -1353,11 +1348,11 @@ NativeProcessDarwin::GetTaskBasicInfo(task_t task,
auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
error.SetError(err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("::task_info(target_task = 0x%4.4x, "
- "flavor = TASK_BASIC_INFO, task_info_out => %p, "
- "task_info_outCnt => %u) failed: %u (%s)",
- m_task, info, count, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "::task_info(target_task = 0x%4.4x, "
+ "flavor = TASK_BASIC_INFO, task_info_out => %p, "
+ "task_info_outCnt => %u) failed: %u (%s)",
+ m_task, info, count, error.GetError(), error.AsCString());
return error;
}
@@ -1368,11 +1363,12 @@ NativeProcessDarwin::GetTaskBasicInfo(task_t task,
(float)info->user_time.microseconds / 1000000.0f;
float system = (float)info->user_time.seconds +
(float)info->user_time.microseconds / 1000000.0f;
- verbose_log->Printf("task_basic_info = { suspend_count = %i, "
- "virtual_size = 0x%8.8llx, resident_size = "
- "0x%8.8llx, user_time = %f, system_time = %f }",
- info->suspend_count, (uint64_t)info->virtual_size,
- (uint64_t)info->resident_size, user, system);
+ verbose_LLDB_LOGF(log,
+ "task_basic_info = { suspend_count = %i, "
+ "virtual_size = 0x%8.8llx, resident_size = "
+ "0x%8.8llx, user_time = %f, system_time = %f }",
+ info->suspend_count, (uint64_t)info->virtual_size,
+ (uint64_t)info->resident_size, user, system);
}
return error;
}
@@ -1383,16 +1379,15 @@ Status NativeProcessDarwin::SuspendTask() {
if (m_task == TASK_NULL) {
error.SetErrorString("task port is null, cannot suspend task");
- if (log)
- log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOGF(log, "NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
return error;
}
auto mach_err = ::task_suspend(m_task);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail() && log)
- log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task);
+ LLDB_LOGF(log, "::task_suspend(target_task = 0x%4.4x)", m_task);
return error;
}
@@ -1401,8 +1396,7 @@ Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
Status error;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__);
if (CanResume()) {
m_thread_actions = resume_actions;
@@ -1412,10 +1406,10 @@ Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
auto state = GetState();
if (state == eStateRunning) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
- "running, ignoring...",
- __FUNCTION__, TaskPortForProcessID(error));
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): task 0x%x is already "
+ "running, ignoring...",
+ __FUNCTION__, TaskPortForProcessID(error));
return error;
}
diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
index 89de92a6df4d..1faa5b219cbc 100644
--- a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
@@ -301,10 +301,10 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- if (log)
- log->Printf("NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = "
- "%u) process stop count = %u",
- __FUNCTION__, process.GetID(), update, process.GetStopID());
+ LLDB_LOGF(log,
+ "NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = "
+ "%u) process stop count = %u",
+ __FUNCTION__, process.GetID(), update, process.GetStopID());
if (process.GetStopID() == 0) {
// On our first stop, we'll record details like 32/64 bitness and select
@@ -346,11 +346,11 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
auto mach_err = ::task_threads(task, &thread_list, &thread_list_count);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("::task_threads(task = 0x%4.4x, thread_list => %p, "
- "thread_list_count => %u) failed: %u (%s)",
- task, thread_list, thread_list_count, error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "::task_threads(task = 0x%4.4x, thread_list => %p, "
+ "thread_list_count => %u) failed: %u (%s)",
+ task, thread_list, thread_list_count, error.GetError(),
+ error.AsCString());
return 0;
}
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index 749835531279..0a49f96f54a1 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -288,9 +288,8 @@ void FreeBSDThread::DidStop() {
void FreeBSDThread::WillResume(lldb::StateType resume_state) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("tid %lu resume_state = %s", GetID(),
- lldb_private::StateAsCString(resume_state));
+ LLDB_LOGF(log, "tid %lu resume_state = %s", GetID(),
+ lldb_private::StateAsCString(resume_state));
ProcessSP process_sp(GetProcess());
ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
int signo = GetResumeSignal();
@@ -322,9 +321,8 @@ bool FreeBSDThread::Resume() {
bool status;
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
- StateAsCString(resume_state));
+ LLDB_LOGF(log, "FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
+ StateAsCString(resume_state));
switch (resume_state) {
default:
@@ -352,9 +350,8 @@ bool FreeBSDThread::Resume() {
void FreeBSDThread::Notify(const ProcessMessage &message) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
- __FUNCTION__, message.PrintKind(), GetID());
+ LLDB_LOGF(log, "FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
+ __FUNCTION__, message.PrintKind(), GetID());
switch (message.GetKind()) {
default:
@@ -457,8 +454,7 @@ void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
// corresponding to our current PC.
assert(GetRegisterContext());
lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
lldb::BreakpointSiteSP bp_site(
GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
@@ -490,10 +486,9 @@ void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
lldb::addr_t halt_addr = message.GetHWAddress();
- if (log)
- log->Printf(
- "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
- __FUNCTION__, halt_addr);
+ LLDB_LOGF(log,
+ "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
+ __FUNCTION__, halt_addr);
POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx) {
@@ -527,8 +522,7 @@ void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
// Try to resolve the breakpoint object corresponding to the current PC.
assert(GetRegisterContext());
lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
lldb::BreakpointSiteSP bp_site(
GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 770794569f72..32e3320150f8 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -154,9 +154,8 @@ Status ProcessFreeBSD::DoResume() {
do_step = true;
}
- if (log)
- log->Printf("process %" PRIu64 " resuming (%s)", GetID(),
- do_step ? "step" : "continue");
+ LLDB_LOGF(log, "process %" PRIu64 " resuming (%s)", GetID(),
+ do_step ? "step" : "continue");
if (do_step && !software_single_step)
m_monitor->SingleStep(GetID(), m_resume_signo);
else
@@ -168,9 +167,8 @@ Status ProcessFreeBSD::DoResume() {
bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- if (log)
- log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
- GetID());
+ LLDB_LOGF(log, "ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
+ GetID());
std::vector<lldb::pid_t> tds;
if (!GetMonitor().GetCurrentThreadIDs(tds)) {
@@ -183,20 +181,18 @@ bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
if (!thread_sp) {
thread_sp.reset(new FreeBSDThread(*this, tid));
- if (log)
- log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__,
+ tid);
} else {
- if (log)
- log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
- tid);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
+ tid);
}
new_thread_list.AddThread(thread_sp);
}
for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
if (old_thread_sp) {
- if (log)
- log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s remove tid", __FUNCTION__);
}
}
@@ -698,14 +694,13 @@ Status ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
user_id_t watchID = wp->GetID();
addr_t addr = wp->GetLoadAddress();
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
+ LLDB_LOGF(log, "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
if (wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
return error;
}
@@ -753,14 +748,13 @@ Status ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
user_id_t watchID = wp->GetID();
addr_t addr = wp->GetLoadAddress();
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
+ LLDB_LOGF(log, "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
if (!wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
+ watchID, (uint64_t)addr);
// This is needed (for now) to keep watchpoints disabled correctly
wp->SetEnabled(false, notify);
return error;
@@ -970,8 +964,9 @@ Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
if (log) {
- log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+ LLDB_LOGF(log, "SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
+ addr);
}
// Validate the address.
@@ -982,11 +977,10 @@ Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
Breakpoint *const sw_step_break =
m_process->GetTarget().CreateBreakpoint(addr, true, false).get();
sw_step_break->SetCallback(SingleStepBreakpointHit, this, true);
- sw_step_break->SetBreakpointKind("software-signle-step");
+ sw_step_break->SetBreakpointKind("software-single-step");
- if (log)
- log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
- __FUNCTION__, addr);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
+ __FUNCTION__, addr);
m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()});
return Status();
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 4b9225db5e39..ff3fb0a75e2d 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -37,9 +37,6 @@
using namespace lldb;
using namespace lldb_private;
-// We disable the tracing of ptrace calls for integration builds to avoid the
-// additional indirection and checks.
-#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
// Wrapper for ptrace to catch errors and log calls.
const char *Get_PT_IO_OP(int op) {
@@ -66,13 +63,14 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
if (log) {
- log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
- reqName, pid, addr, data, file, line);
+ LLDB_LOGF(log,
+ "ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
+ reqName, pid, addr, data, file, line);
if (req == PT_IO) {
struct ptrace_io_desc *pi = (struct ptrace_io_desc *)addr;
- log->Printf("PT_IO: op=%s offs=%zx size=%zu", Get_PT_IO_OP(pi->piod_op),
- (size_t)pi->piod_offs, pi->piod_len);
+ LLDB_LOGF(log, "PT_IO: op=%s offs=%zx size=%zu",
+ Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len);
}
}
@@ -101,7 +99,7 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
default:
str = "<unknown>";
}
- log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
+ LLDB_LOGF(log, "ptrace() failed; errno=%d (%s)", errno, str);
}
if (log) {
@@ -109,15 +107,15 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
if (req == PT_GETREGS) {
struct reg *r = (struct reg *)addr;
- log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
- r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
+ LLDB_LOGF(log, "PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
+ r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
}
if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
struct dbreg *r = (struct dbreg *)addr;
char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
for (int i = 0; i <= 7; i++)
- log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
+ LLDB_LOGF(log, "PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
}
#endif
}
@@ -136,9 +134,6 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) {
#define PTRACE(req, pid, addr, data) \
PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
-#else
-PtraceWrapper((req), (pid), (addr), (data))
-#endif
// Static implementations of ProcessMonitor::ReadMemory and
// ProcessMonitor::WriteMemory. This enables mutual recursion between these
@@ -708,7 +703,7 @@ ProcessMonitor::ProcessMonitor(
const lldb_private::ProcessLaunchInfo & /* launch_info */,
lldb_private::Status &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
- m_operation_thread(nullptr), m_monitor_thread(nullptr), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
+ m_operation_thread(), m_monitor_thread(), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
using namespace std::placeholders;
std::unique_ptr<LaunchArgs> args(
@@ -735,20 +730,22 @@ ProcessMonitor::ProcessMonitor(
}
// Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
+ llvm::Expected<lldb_private::HostThread> monitor_thread =
+ Host::StartMonitoringChildProcess(
std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
GetPID(), true);
- if (!m_monitor_thread->IsJoinable()) {
+ if (!monitor_thread || !monitor_thread->IsJoinable()) {
error.SetErrorToGenericError();
error.SetErrorString("Process launch failed.");
return;
}
+ m_monitor_thread = *monitor_thread;
}
ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
lldb_private::Status &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
- m_operation_thread(nullptr), m_monitor_thread(nullptr), m_pid(pid), m_terminal_fd(-1), m_operation(0) {
+ m_operation_thread(), m_monitor_thread(), m_pid(pid), m_terminal_fd(-1), m_operation(0) {
using namespace std::placeholders;
sem_init(&m_operation_pending, 0, 0);
@@ -773,14 +770,16 @@ ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
}
// Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
+ llvm::Expected<lldb_private::HostThread> monitor_thread =
+ Host::StartMonitoringChildProcess(
std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
GetPID(), true);
- if (!m_monitor_thread->IsJoinable()) {
+ if (!monitor_thread || !monitor_thread->IsJoinable()) {
error.SetErrorToGenericError();
error.SetErrorString("Process attach failed.");
return;
}
+ m_monitor_thread = *monitor_thread;
}
ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
@@ -789,13 +788,15 @@ ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
void ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Status &error) {
static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread->IsJoinable())
+ if (m_operation_thread && m_operation_thread->IsJoinable())
return;
- m_operation_thread =
- ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args);
- if (!m_operation_thread)
- error = m_operation_thread.takeError();
+ llvm::Expected<lldb_private::HostThread> operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args);
+ if (operation_thread)
+ m_operation_thread = *operation_thread;
+ else
+ error = operation_thread.takeError();
}
void *ProcessMonitor::LaunchOpThread(void *arg) {
@@ -957,14 +958,15 @@ void ProcessMonitor::StartAttachOpThread(AttachArgs *args,
lldb_private::Status &error) {
static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread->IsJoinable())
+ if (m_operation_thread && m_operation_thread->IsJoinable())
return;
- m_operation_thread =
- ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args);
-
- if (!m_operation_thread)
- error = m_operation_thread.takeError();
+ llvm::Expected<lldb_private::HostThread> operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args);
+ if (operation_thread)
+ m_operation_thread = *operation_thread;
+ else
+ error = operation_thread.takeError();
}
void *ProcessMonitor::AttachOpThread(void *arg) {
@@ -1037,9 +1039,8 @@ bool ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
if (exited) {
- if (log)
- log->Printf("ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
- __FUNCTION__, pid);
+ LLDB_LOGF(log, "ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
+ __FUNCTION__, pid);
message = ProcessMessage::Exit(pid, status);
process->SendMessage(message);
return pid == process->GetID();
@@ -1087,10 +1088,10 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
unsigned long data = 0;
if (!monitor->GetEventMessage(tid, &data))
data = -1;
- if (log)
- log->Printf("ProcessMonitor::%s() received exit? event, data = %lx, tid "
- "= %" PRIu64,
- __FUNCTION__, data, tid);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received exit? event, data = %lx, tid "
+ "= %" PRIu64,
+ __FUNCTION__, data, tid);
message = ProcessMessage::Limbo(tid, (data >> 8));
break;
}
@@ -1101,26 +1102,25 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
// Map TRAP_CAP to a trace trap in the absense of a more specific handler.
case TRAP_CAP:
#endif
- if (log)
- log->Printf("ProcessMonitor::%s() received trace event, tid = %" PRIu64
- " : si_code = %d",
- __FUNCTION__, tid, info->si_code);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received trace event, tid = %" PRIu64
+ " : si_code = %d",
+ __FUNCTION__, tid, info->si_code);
message = ProcessMessage::Trace(tid);
break;
case SI_KERNEL:
case TRAP_BRKPT:
if (monitor->m_process->IsSoftwareStepBreakpoint(tid)) {
- if (log)
- log->Printf("ProcessMonitor::%s() received sw single step breakpoint "
- "event, tid = %" PRIu64,
- __FUNCTION__, tid);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received sw single step breakpoint "
+ "event, tid = %" PRIu64,
+ __FUNCTION__, tid);
message = ProcessMessage::Trace(tid);
} else {
- if (log)
- log->Printf(
- "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
- __FUNCTION__, tid);
+ LLDB_LOGF(
+ log, "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
+ __FUNCTION__, tid);
message = ProcessMessage::Break(tid);
}
break;
@@ -1146,22 +1146,19 @@ ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
//
// Similarly, ACK signals generated by this monitor.
if (info->si_code == SI_USER) {
- if (log)
- log->Printf(
- "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
- __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
- "SI_USER", info->si_pid);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
+ __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
+ "SI_USER", info->si_pid);
if (info->si_pid == getpid())
return ProcessMessage::SignalDelivered(tid, signo);
else
return ProcessMessage::Signal(tid, signo);
}
- if (log)
- log->Printf(
- "ProcessMonitor::%s() received signal %s", __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
+ LLDB_LOGF(log, "ProcessMonitor::%s() received signal %s", __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
switch (signo) {
case SIGSEGV:
@@ -1313,14 +1310,14 @@ bool ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) {
m_process->GetUnixSignals()->GetSignalAsCString(signo);
if (signame == nullptr)
signame = "<none>";
- log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
- __FUNCTION__, GetPID(), signame);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
+ __FUNCTION__, GetPID(), signame);
}
ResumeOperation op(signo, result);
DoOperation(&op);
- if (log)
- log->Printf("ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
- result ? "true" : "false");
+ LLDB_LOGF(log, "ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
+ result ? "true" : "false");
return result;
}
@@ -1384,7 +1381,7 @@ bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd,
}
void ProcessMonitor::StopMonitoringChildProcess() {
- if (m_monitor_thread->IsJoinable()) {
+ if (m_monitor_thread && m_monitor_thread->IsJoinable()) {
m_monitor_thread->Cancel();
m_monitor_thread->Join(nullptr);
m_monitor_thread->Reset();
@@ -1422,10 +1419,9 @@ void ProcessMonitor::StopMonitor() {
bool ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) { return true; }
void ProcessMonitor::StopOpThread() {
- if (!m_operation_thread->IsJoinable())
- return;
-
- m_operation_thread->Cancel();
- m_operation_thread->Join(nullptr);
- m_operation_thread->Reset();
+ if (m_operation_thread && m_operation_thread->IsJoinable()) {
+ m_operation_thread->Cancel();
+ m_operation_thread->Join(nullptr);
+ m_operation_thread->Reset();
+ }
}
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 2adcc449c5c6..c5edfc0be95a 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -183,8 +183,8 @@ public:
private:
ProcessFreeBSD *m_process;
- llvm::Expected<lldb_private::HostThread> m_operation_thread;
- llvm::Expected<lldb_private::HostThread> m_monitor_thread;
+ llvm::Optional<lldb_private::HostThread> m_operation_thread;
+ llvm::Optional<lldb_private::HostThread> m_monitor_thread;
lldb::pid_t m_pid;
int m_terminal_fd;
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 32d20d2b1215..8b6f9fbc33c3 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -140,7 +140,7 @@ NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd,
NativeDelegate &delegate,
const ArchSpec &arch,
MainLoop &mainloop)
- : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
+ : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
if (m_terminal_fd != -1) {
Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
assert(status.Success());
@@ -195,6 +195,7 @@ void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) {
SIGSTOP, &info.psi_siginfo);
}
}
+ SetState(StateType::eStateStopped, true);
}
}
@@ -339,12 +340,14 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
}
Status error;
+ int signal =
+ action->signal != LLDB_INVALID_SIGNAL_NUMBER ? action->signal : 0;
switch (action->state) {
case eStateRunning: {
// Run the thread, possibly feeding it the signal.
error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1,
- action->signal);
+ signal);
if (!error.Success())
return error;
for (const auto &thread : m_threads)
@@ -355,7 +358,7 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
case eStateStepping:
// Run the thread, possibly feeding it the signal.
error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1,
- action->signal);
+ signal);
if (!error.Success())
return error;
for (const auto &thread : m_threads)
@@ -658,7 +661,7 @@ NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
if (m_threads.empty())
SetCurrentThreadID(thread_id);
- m_threads.push_back(llvm::make_unique<NativeThreadNetBSD>(*this, thread_id));
+ m_threads.push_back(std::make_unique<NativeThreadNetBSD>(*this, thread_id));
return static_cast<NativeThreadNetBSD &>(*m_threads.back());
}
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index e85ca3b7a925..4e7f0a1c13ab 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -9,12 +9,12 @@
#ifndef liblldb_NativeProcessNetBSD_H_
#define liblldb_NativeProcessNetBSD_H_
+#include "Plugins/Process/POSIX/NativeProcessELF.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "NativeThreadNetBSD.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
namespace lldb_private {
namespace process_netbsd {
@@ -25,7 +25,7 @@ namespace process_netbsd {
/// for debugging.
///
/// Changes in the inferior process state are broadcasted.
-class NativeProcessNetBSD : public NativeProcessProtocol {
+class NativeProcessNetBSD : public NativeProcessELF {
public:
class Factory : public NativeProcessProtocol::Factory {
public:
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index a7cd637bf826..6cc2810fa235 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -906,8 +906,8 @@ uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint(
return wp_index;
}
if (error.Fail() && log) {
- log->Printf("NativeRegisterContextNetBSD_x86_64::%s Error: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "NativeRegisterContextNetBSD_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
}
}
return LLDB_INVALID_INDEX32;
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp
index 70c2687e3b8c..9678e48436e7 100644
--- a/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -229,11 +229,6 @@ std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
}
const char *CrashReasonAsString(CrashReason reason) {
-#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
-#else
const char *str = nullptr;
switch (reason) {
@@ -315,8 +310,6 @@ const char *CrashReasonAsString(CrashReason reason) {
str = "eFloatSubscriptRange";
break;
}
-#endif
-
return str;
}
diff --git a/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/source/Plugins/Process/POSIX/NativeProcessELF.cpp
index 559b16c8fd69..058dc5ae2338 100644
--- a/source/Plugins/Process/POSIX/NativeProcessELF.cpp
+++ b/source/Plugins/Process/POSIX/NativeProcessELF.cpp
@@ -21,7 +21,7 @@ NativeProcessELF::GetAuxValue(enum AuxVector::EntryType type) {
DataExtractor auxv_data(buffer_or_error.get()->getBufferStart(),
buffer_or_error.get()->getBufferSize(),
GetByteOrder(), GetAddressByteSize());
- m_aux_vector = llvm::make_unique<AuxVector>(auxv_data);
+ m_aux_vector = std::make_unique<AuxVector>(auxv_data);
}
return m_aux_vector->GetAuxValue(type);
@@ -107,4 +107,72 @@ lldb::addr_t NativeProcessELF::GetELFImageInfoAddress() {
return LLDB_INVALID_ADDRESS;
}
-} // namespace lldb_private \ No newline at end of file
+template <typename T>
+llvm::Expected<SVR4LibraryInfo>
+NativeProcessELF::ReadSVR4LibraryInfo(lldb::addr_t link_map_addr) {
+ ELFLinkMap<T> link_map;
+ size_t bytes_read;
+ auto error =
+ ReadMemory(link_map_addr, &link_map, sizeof(link_map), bytes_read);
+ if (!error.Success())
+ return error.ToError();
+
+ char name_buffer[PATH_MAX];
+ llvm::Expected<llvm::StringRef> string_or_error = ReadCStringFromMemory(
+ link_map.l_name, &name_buffer[0], sizeof(name_buffer), bytes_read);
+ if (!string_or_error)
+ return string_or_error.takeError();
+
+ SVR4LibraryInfo info;
+ info.name = string_or_error->str();
+ info.link_map = link_map_addr;
+ info.base_addr = link_map.l_addr;
+ info.ld_addr = link_map.l_ld;
+ info.next = link_map.l_next;
+
+ return info;
+}
+
+llvm::Expected<std::vector<SVR4LibraryInfo>>
+NativeProcessELF::GetLoadedSVR4Libraries() {
+ // Address of DT_DEBUG.d_ptr which points to r_debug
+ lldb::addr_t info_address = GetSharedLibraryInfoAddress();
+ if (info_address == LLDB_INVALID_ADDRESS)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid shared library info address");
+ // Address of r_debug
+ lldb::addr_t address = 0;
+ size_t bytes_read;
+ auto status =
+ ReadMemory(info_address, &address, GetAddressByteSize(), bytes_read);
+ if (!status.Success())
+ return status.ToError();
+ if (address == 0)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid r_debug address");
+ // Read r_debug.r_map
+ lldb::addr_t link_map = 0;
+ status = ReadMemory(address + GetAddressByteSize(), &link_map,
+ GetAddressByteSize(), bytes_read);
+ if (!status.Success())
+ return status.ToError();
+ if (address == 0)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid link_map address");
+
+ std::vector<SVR4LibraryInfo> library_list;
+ while (link_map) {
+ llvm::Expected<SVR4LibraryInfo> info =
+ GetAddressByteSize() == 8 ? ReadSVR4LibraryInfo<uint64_t>(link_map)
+ : ReadSVR4LibraryInfo<uint32_t>(link_map);
+ if (!info)
+ return info.takeError();
+ if (!info->name.empty() && info->base_addr != 0)
+ library_list.push_back(*info);
+ link_map = info->next;
+ }
+
+ return library_list;
+}
+
+} // namespace lldb_private
diff --git a/source/Plugins/Process/POSIX/NativeProcessELF.h b/source/Plugins/Process/POSIX/NativeProcessELF.h
index 84dc8d08a340..4fb513baebf0 100644
--- a/source/Plugins/Process/POSIX/NativeProcessELF.h
+++ b/source/Plugins/Process/POSIX/NativeProcessELF.h
@@ -37,6 +37,13 @@ protected:
template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
lldb::addr_t GetELFImageInfoAddress();
+ llvm::Expected<std::vector<SVR4LibraryInfo>>
+ GetLoadedSVR4Libraries() override;
+
+ template <typename T>
+ llvm::Expected<SVR4LibraryInfo>
+ ReadSVR4LibraryInfo(lldb::addr_t link_map_addr);
+
std::unique_ptr<AuxVector> m_aux_vector;
llvm::Optional<lldb::addr_t> m_shared_library_info_addr;
};
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index aa8449131a68..66286dd3d9e3 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -15,11 +15,6 @@ const char *ProcessMessage::PrintCrashReason() const {
}
const char *ProcessMessage::PrintKind(Kind kind) {
-#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
-#else
const char *str = nullptr;
switch (kind) {
@@ -60,8 +55,6 @@ const char *ProcessMessage::PrintKind(Kind kind) {
str = "eExecMessage";
break;
}
-#endif
-
return str;
}
diff --git a/source/Plugins/Process/Utility/AuxVector.cpp b/source/Plugins/Process/Utility/AuxVector.cpp
index aab164ff93a6..25a1d0b5af06 100644
--- a/source/Plugins/Process/Utility/AuxVector.cpp
+++ b/source/Plugins/Process/Utility/AuxVector.cpp
@@ -43,9 +43,9 @@ void AuxVector::DumpToLog(lldb_private::Log *log) const {
log->PutCString("AuxVector: ");
for (auto entry : m_auxv_entries) {
- log->Printf(" %s [%" PRIu64 "]: %" PRIx64,
- GetEntryName(static_cast<EntryType>(entry.first)), entry.first,
- entry.second);
+ LLDB_LOGF(log, " %s [%" PRIu64 "]: %" PRIx64,
+ GetEntryName(static_cast<EntryType>(entry.first)), entry.first,
+ entry.second);
}
}
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 1afe4d920599..a86880af2260 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -137,76 +137,67 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
// ends at
static RegularExpression g_bitfield_regex(
llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"));
- RegularExpression::Match regex_match(3);
- if (g_bitfield_regex.Execute(slice_str, &regex_match)) {
- llvm::StringRef reg_name_str;
- std::string msbit_str;
- std::string lsbit_str;
- if (regex_match.GetMatchAtIndex(slice_str, 1, reg_name_str) &&
- regex_match.GetMatchAtIndex(slice_str, 2, msbit_str) &&
- regex_match.GetMatchAtIndex(slice_str, 3, lsbit_str)) {
- const uint32_t msbit =
- StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
- const uint32_t lsbit =
- StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
- if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
- if (msbit > lsbit) {
- const uint32_t msbyte = msbit / 8;
- const uint32_t lsbyte = lsbit / 8;
-
- ConstString containing_reg_name(reg_name_str);
-
- const RegisterInfo *containing_reg_info =
- GetRegisterInfo(containing_reg_name);
- if (containing_reg_info) {
- const uint32_t max_bit = containing_reg_info->byte_size * 8;
- if (msbit < max_bit && lsbit < max_bit) {
- m_invalidate_regs_map[containing_reg_info
- ->kinds[eRegisterKindLLDB]]
- .push_back(i);
- m_value_regs_map[i].push_back(
- containing_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[i].push_back(
- containing_reg_info->kinds[eRegisterKindLLDB]);
-
- if (byte_order == eByteOrderLittle) {
- success = true;
- reg_info.byte_offset =
- containing_reg_info->byte_offset + lsbyte;
- } else if (byte_order == eByteOrderBig) {
- success = true;
- reg_info.byte_offset =
- containing_reg_info->byte_offset + msbyte;
- } else {
- llvm_unreachable("Invalid byte order");
- }
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (g_bitfield_regex.Execute(slice_str, &matches)) {
+ std::string reg_name_str = matches[1].str();
+ std::string msbit_str = matches[2].str();
+ std::string lsbit_str = matches[3].str();
+ const uint32_t msbit =
+ StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
+ const uint32_t lsbit =
+ StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
+ if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
+ if (msbit > lsbit) {
+ const uint32_t msbyte = msbit / 8;
+ const uint32_t lsbyte = lsbit / 8;
+
+ ConstString containing_reg_name(reg_name_str);
+
+ const RegisterInfo *containing_reg_info =
+ GetRegisterInfo(containing_reg_name);
+ if (containing_reg_info) {
+ const uint32_t max_bit = containing_reg_info->byte_size * 8;
+ if (msbit < max_bit && lsbit < max_bit) {
+ m_invalidate_regs_map[containing_reg_info
+ ->kinds[eRegisterKindLLDB]]
+ .push_back(i);
+ m_value_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+
+ if (byte_order == eByteOrderLittle) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + lsbyte;
+ } else if (byte_order == eByteOrderBig) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + msbyte;
} else {
- if (msbit > max_bit)
- printf("error: msbit (%u) must be less than the bitsize "
- "of the register (%u)\n",
- msbit, max_bit);
- else
- printf("error: lsbit (%u) must be less than the bitsize "
- "of the register (%u)\n",
- lsbit, max_bit);
+ llvm_unreachable("Invalid byte order");
}
} else {
- printf("error: invalid concrete register \"%s\"\n",
- containing_reg_name.GetCString());
+ if (msbit > max_bit)
+ printf("error: msbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ msbit, max_bit);
+ else
+ printf("error: lsbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ lsbit, max_bit);
}
} else {
- printf("error: msbit (%u) must be greater than lsbit (%u)\n",
- msbit, lsbit);
+ printf("error: invalid concrete register \"%s\"\n",
+ containing_reg_name.GetCString());
}
} else {
- printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
- lsbit);
+ printf("error: msbit (%u) must be greater than lsbit (%u)\n",
+ msbit, lsbit);
}
} else {
- // TODO: print error invalid slice string that doesn't follow the
- // format
- printf("error: failed to extract regex matches for parsing the "
- "register bitfield regex\n");
+ printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
+ lsbit);
}
} else {
// TODO: print error invalid slice string that doesn't follow the
@@ -545,6 +536,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
if (!generic_regs_specified) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::aarch64_be:
for (auto &reg : m_regs) {
if (strcmp(reg.name, "pc") == 0)
diff --git a/source/Plugins/Process/Utility/HistoryThread.cpp b/source/Plugins/Process/Utility/HistoryThread.cpp
index 3cb583172623..295c17e474fb 100644
--- a/source/Plugins/Process/Utility/HistoryThread.cpp
+++ b/source/Plugins/Process/Utility/HistoryThread.cpp
@@ -32,17 +32,15 @@ HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
m_queue_id(LLDB_INVALID_QUEUE_ID) {
m_unwinder_up.reset(new HistoryUnwind(*this, pcs));
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
+ LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this));
}
// Destructor
HistoryThread::~HistoryThread() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
- static_cast<void *>(this), GetID());
+ LLDB_LOGF(log, "%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
+ static_cast<void *>(this), GetID());
DestroyThread();
}
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.cpp b/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 7d473bff8200..83fdb011f5a1 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -51,13 +51,15 @@ HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
}
bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) {
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) {
// FIXME do not throw away the lock after we acquire it..
std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
guard.unlock();
if (frame_idx < m_pcs.size()) {
cfa = frame_idx;
pc = m_pcs[frame_idx];
+ behaves_like_zeroth_frame = (frame_idx == 0);
return true;
}
return false;
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h
index 6c4522e6b35b..4d16608bd8c2 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -29,7 +29,8 @@ protected:
DoCreateRegisterContextForFrame(StackFrame *frame) override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) override;
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) override;
uint32_t DoGetFrameCount() override;
private:
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 9beaf2fc7ac8..2ccbeacc4960 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -12,7 +12,7 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Host/Config.h"
-#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
@@ -41,13 +41,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
if (thread == nullptr)
return false;
- const bool append = true;
const bool include_symbols = true;
const bool include_inlines = false;
SymbolContextList sc_list;
- const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ process->GetTarget().GetImages().FindFunctions(
ConstString("mmap"), eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
+ const uint32_t count = sc_list.GetSize();
if (count > 0) {
SymbolContext sc;
if (sc_list.GetContextAtIndex(0, sc)) {
@@ -79,17 +79,23 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
AddressRange mmap_range;
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
mmap_range)) {
- ClangASTContext *clang_ast_context =
- process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ auto type_system_or_err =
+ process->GetTarget().GetScratchTypeSystemForLanguage(
+ eLanguageTypeC);
+ if (!type_system_or_err) {
+ llvm::consumeError(type_system_or_err.takeError());
+ return false;
+ }
+ CompilerType void_ptr_type =
+ type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid)
+ .GetPointerType();
const ArchSpec arch = process->GetTarget().GetArchitecture();
MmapArgList args =
process->GetTarget().GetPlatform()->GetMmapArgumentList(
arch, addr, length, prot_arg, flags, fd, offset);
lldb::ThreadPlanSP call_plan_sp(
new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
- clang_void_ptr_type, args, options));
+ void_ptr_type, args, options));
if (call_plan_sp) {
DiagnosticManager diagnostics;
@@ -129,13 +135,13 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
if (thread == nullptr)
return false;
- const bool append = true;
const bool include_symbols = true;
const bool include_inlines = false;
SymbolContextList sc_list;
- const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ process->GetTarget().GetImages().FindFunctions(
ConstString("munmap"), eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
+ const uint32_t count = sc_list.GetSize();
if (count > 0) {
SymbolContext sc;
if (sc_list.GetContextAtIndex(0, sc)) {
@@ -178,60 +184,3 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
return false;
}
-
-// FIXME: This has nothing to do with Posix, it is just a convenience function
-// that calls a
-// function of the form "void * (*)(void)". We should find a better place to
-// put this.
-
-bool lldb_private::InferiorCall(Process *process, const Address *address,
- addr_t &returned_func, bool trap_exceptions) {
- Thread *thread =
- process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == nullptr || address == nullptr)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug(false);
- options.SetTimeout(process->GetUtilityExpressionTimeout());
- options.SetTrapExceptions(trap_exceptions);
-
- ClangASTContext *clang_ast_context =
- process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::ThreadPlanSP call_plan_sp(
- new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type,
- llvm::ArrayRef<addr_t>(), options));
- if (call_plan_sp) {
- DiagnosticManager diagnostics;
-
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame) {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext(exe_ctx);
- ExpressionResults result =
- process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted) {
- returned_func =
- call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
- LLDB_INVALID_ADDRESS);
-
- if (process->GetAddressByteSize() == 4) {
- if (returned_func == UINT32_MAX)
- return false;
- } else if (process->GetAddressByteSize() == 8) {
- if (returned_func == UINT64_MAX)
- return false;
- }
- return true;
- }
- }
- }
-
- return false;
-}
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
index 04316801b351..2008c5fe0b91 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.h
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
@@ -30,9 +30,6 @@ bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr,
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
-bool InferiorCall(Process *proc, const Address *address,
- lldb::addr_t &returned_func, bool trap_exceptions = false);
-
} // namespace lldb_private
#endif // lldb_InferiorCallPOSIX_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index e804a4d251f7..4ca33c248c6f 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -1111,9 +1111,10 @@ int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
if (log) {
for (uint32_t i = 0; i < 16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
- "0x%8.8x, 0x%8.8x }",
- i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ LLDB_LOGF(log,
+ "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
+ "0x%8.8x, 0x%8.8x }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
}
}
@@ -1514,8 +1515,6 @@ uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
// Zero is reserved for the BRP count, so don't increment it if it is zero
if (g_num_supported_hw_breakpoints > 0)
g_num_supported_hw_breakpoints++;
- // if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)",
- // register_DBGDIDR, g_num_supported_hw_breakpoints);
}
return g_num_supported_hw_breakpoints;
#else
@@ -1642,8 +1641,6 @@ uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
uint32_t register_DBGDIDR;
asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
- // if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)",
- // register_DBGDIDR, g_num_supported_hw_watchpoints);
}
return g_num_supported_hw_watchpoints;
#else
@@ -1656,10 +1653,6 @@ uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
size_t size,
bool read,
bool write) {
- // if (log) log->Printf
- // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size
- // = %u, read = %u, write = %u)", addr, size, read, write);
-
const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
// Can't watch zero bytes
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 85d518a487bf..b3ec24d8905d 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -25,6 +25,11 @@
#include <memory>
+#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__))
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
// Support building against older versions of LLVM, this macro was added
// recently.
#ifndef LLVM_EXTENSION
@@ -285,10 +290,11 @@ int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) {
void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) {
if (log) {
for (uint32_t i = 0; i < 16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64
- " } WVR%-2u/WCR%-2u "
- "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }",
- i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ LLDB_LOGF(log,
+ "BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64
+ " } WVR%-2u/WCR%-2u "
+ "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
}
}
@@ -423,7 +429,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- value.SetBytes(fpu.v[reg - fpu_v0].bytes.buffer, reg_info->byte_size,
+ value.SetBytes(fpu.v[reg - fpu_v0].bytes, reg_info->byte_size,
endian::InlHostByteOrder());
break;
@@ -502,7 +508,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
case fpu_d31: {
ProcessSP process_sp(m_thread.GetProcess());
if (process_sp.get()) {
- DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(),
+ DataExtractor regdata(&fpu.v[reg - fpu_d0], 8, process_sp->GetByteOrder(),
process_sp->GetAddressByteSize());
offset_t offset = 0;
value.SetDouble(regdata.GetDouble(&offset));
@@ -615,7 +621,7 @@ bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- ::memcpy(fpu.v[reg - fpu_v0].bytes.buffer, value.GetBytes(),
+ ::memcpy(fpu.v[reg - fpu_v0].bytes, value.GetBytes(),
value.GetByteSize());
break;
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index 2f691c807d50..abb87e3c2348 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -73,7 +73,7 @@ public:
};
struct VReg {
- llvm::AlignedCharArray<16, 16> bytes;
+ alignas(16) char bytes[16];
};
// mirrors <mach/arm/thread_status.h> arm_neon_state64_t
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index 820d280c37f7..873713fd8373 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -496,11 +496,11 @@ int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {
if (log) {
if (title)
- log->Printf("%s", title);
+ LLDB_LOGF(log, "%s", title);
for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
uint32_t reg = gpr_eax + i;
- log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name,
- (&gpr.eax)[reg]);
+ LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name,
+ (&gpr.eax)[reg]);
}
}
}
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index 62e512adc9f7..47758ce85eb2 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -554,22 +554,6 @@ int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) {
return -1;
}
-void RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) {
- if (log) {
- if (format) {
- va_list args;
- va_start(args, format);
- log->VAPrintf(format, args);
- va_end(args);
- }
- for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
- uint32_t reg = gpr_rax + i;
- log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name,
- (&gpr.rax)[reg]);
- }
- }
-}
-
int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
int set = GPRRegSet;
if (force || !RegisterSetIsCached(set)) {
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 76646d8897d1..49a589f14989 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -12,12 +12,14 @@
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
+#include "lldb/Symbol/CallFrameInfo.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
@@ -150,15 +152,8 @@ void RegisterContextLLDB::InitializeZerothFrame() {
UnwindLogMsg("using architectural default unwind method");
}
- // We require either a symbol or function in the symbols context to be
- // successfully filled in or this context is of no use to us.
- const SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
- if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress(
- m_current_pc, resolve_scope, m_sym_ctx) &
- resolve_scope)) {
- m_sym_ctx_valid = true;
- }
+ AddressRange addr_range;
+ m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
if (m_sym_ctx.symbol) {
UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
@@ -172,9 +167,6 @@ void RegisterContextLLDB::InitializeZerothFrame() {
current_pc);
}
- AddressRange addr_range;
- m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range);
-
if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
m_frame_type = eTrapHandlerFrame;
} else {
@@ -436,24 +428,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
return;
}
- bool resolve_tail_call_address = false; // m_current_pc can be one past the
- // address range of the function...
- // If the saved pc does not point to a function/symbol because it is beyond
- // the bounds of the correct function and there's no symbol there, we do
- // *not* want ResolveSymbolContextForAddress to back up the pc by 1, because
- // then we might not find the correct unwind information later. Instead, let
- // ResolveSymbolContextForAddress fail, and handle the case via
- // decr_pc_and_recompute_addr_range below.
- const SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
- uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress(
- m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address);
-
- // We require either a symbol or function in the symbols context to be
- // successfully filled in or this context is of no use to us.
- if (resolve_scope & resolved_scope) {
- m_sym_ctx_valid = true;
- }
+ AddressRange addr_range;
+ m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
if (m_sym_ctx.symbol) {
UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc,
@@ -467,25 +443,30 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
pc);
}
- AddressRange addr_range;
- if (!m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range)) {
- m_sym_ctx_valid = false;
- }
+ bool decr_pc_and_recompute_addr_range;
- bool decr_pc_and_recompute_addr_range = false;
-
- // If the symbol lookup failed...
- if (!m_sym_ctx_valid)
+ if (!m_sym_ctx_valid) {
+ // Always decrement and recompute if the symbol lookup failed
decr_pc_and_recompute_addr_range = true;
-
- // Or if we're in the middle of the stack (and not "above" an asynchronous
- // event like sigtramp), and our "current" pc is the start of a function...
- if (GetNextFrame()->m_frame_type != eTrapHandlerFrame &&
- GetNextFrame()->m_frame_type != eDebuggerFrame &&
- (!m_sym_ctx_valid ||
- (addr_range.GetBaseAddress().IsValid() &&
- addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() &&
- addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()))) {
+ } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
+ GetNextFrame()->m_frame_type == eDebuggerFrame) {
+ // Don't decrement if we're "above" an asynchronous event like
+ // sigtramp.
+ decr_pc_and_recompute_addr_range = false;
+ } else if (!addr_range.GetBaseAddress().IsValid() ||
+ addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() ||
+ addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) {
+ // If our "current" pc isn't the start of a function, no need
+ // to decrement and recompute.
+ decr_pc_and_recompute_addr_range = false;
+ } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
+ // Signal dispatch may set the return address of the handler it calls to
+ // point to the first byte of a return trampoline (like __kernel_rt_sigreturn),
+ // so do not decrement and recompute if the symbol we already found is a trap
+ // handler.
+ decr_pc_and_recompute_addr_range = false;
+ } else {
+ // Decrement to find the function containing the call.
decr_pc_and_recompute_addr_range = true;
}
@@ -502,18 +483,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
Address temporary_pc;
temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
m_sym_ctx.Clear(false);
- m_sym_ctx_valid = false;
- SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
-
- ModuleSP temporary_module_sp = temporary_pc.GetModule();
- if (temporary_module_sp &&
- temporary_module_sp->ResolveSymbolContextForAddress(
- temporary_pc, resolve_scope, m_sym_ctx) &
- resolve_scope) {
- if (m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range))
- m_sym_ctx_valid = true;
- }
+ m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
+
UnwindLogMsg("Symbol is now %s",
GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
}
@@ -563,6 +534,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
active_row =
m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
+ PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp);
if (active_row.get() && log) {
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
@@ -575,6 +547,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) {
active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
+ PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
if (active_row.get() && log) {
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
@@ -812,6 +785,16 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
unwind_plan_sp.reset();
}
+ CallFrameInfo *object_file_unwind =
+ pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo();
+ if (object_file_unwind) {
+ unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
+ return unwind_plan_sp;
+ else
+ unwind_plan_sp.reset();
+ }
+
return arch_default_unwind_plan_sp;
}
@@ -824,6 +807,9 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
m_fast_unwind_plan_sp.reset();
unwind_plan_sp =
func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
+ if (!unwind_plan_sp)
+ unwind_plan_sp =
+ func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
return unwind_plan_sp;
@@ -846,6 +832,9 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// intend) or compact unwind (this won't work)
unwind_plan_sp =
func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
+ if (!unwind_plan_sp)
+ unwind_plan_sp =
+ func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the "
"DynamicLoader suggested we prefer it",
@@ -1512,8 +1501,7 @@ RegisterContextLLDB::SavedLocationForRegister(
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
- unwindplan_regloc.GetDWARFExpressionLength());
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
dwarfexpr.SetRegisterKind(unwindplan_registerkind);
Value cfa_val = Scalar(m_cfa);
cfa_val.SetValueType(Value::eValueTypeLoadAddress);
@@ -1698,6 +1686,7 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
// We've copied the fallback unwind plan into the full - now clear the
// fallback.
m_fallback_unwind_plan_sp.reset();
+ PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
}
return true;
@@ -1741,6 +1730,8 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
m_cfa = new_cfa;
+ PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
+
UnwindLogMsg("switched unconditionally to the fallback unwindplan %s",
m_full_unwind_plan_sp->GetSourceName().GetCString());
return true;
@@ -1748,6 +1739,53 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
return false;
}
+void RegisterContextLLDB::PropagateTrapHandlerFlagFromUnwindPlan(
+ lldb::UnwindPlanSP unwind_plan) {
+ if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
+ // Unwind plan does not indicate trap handler. Do nothing. We may
+ // already be flagged as trap handler flag due to the symbol being
+ // in the trap handler symbol list, and that should take precedence.
+ return;
+ } else if (m_frame_type != eNormalFrame) {
+ // If this is already a trap handler frame, nothing to do.
+ // If this is a skip or debug or invalid frame, don't override that.
+ return;
+ }
+
+ m_frame_type = eTrapHandlerFrame;
+
+ if (m_current_offset_backed_up_one != m_current_offset) {
+ // We backed up the pc by 1 to compute the symbol context, but
+ // now need to undo that because the pc of the trap handler
+ // frame may in fact be the first instruction of a signal return
+ // trampoline, rather than the instruction after a call. This
+ // happens on systems where the signal handler dispatch code, rather
+ // than calling the handler and being returned to, jumps to the
+ // handler after pushing the address of a return trampoline on the
+ // stack -- on these systems, when the handler returns, control will
+ // be transferred to the return trampoline, so that's the best
+ // symbol we can present in the callstack.
+ UnwindLogMsg("Resetting current offset and re-doing symbol lookup; "
+ "old symbol was %s",
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ m_current_offset_backed_up_one = m_current_offset;
+
+ AddressRange addr_range;
+ m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
+
+ UnwindLogMsg("Symbol is now %s",
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ Target *target = &process->GetTarget();
+
+ m_start_pc = addr_range.GetBaseAddress();
+ m_current_offset =
+ m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target);
+ }
+}
+
bool RegisterContextLLDB::ReadFrameAddress(
lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa,
addr_t &address) {
@@ -1816,8 +1854,7 @@ bool RegisterContextLLDB::ReadFrameAddress(
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
- fa.GetDWARFExpressionLength());
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
dwarfexpr.SetRegisterKind(row_register_kind);
Value result;
Status error;
@@ -1833,12 +1870,66 @@ bool RegisterContextLLDB::ReadFrameAddress(
error.AsCString());
break;
}
+ case UnwindPlan::Row::FAValue::isRaSearch: {
+ Process &process = *m_thread.GetProcess();
+ lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset());
+ if (return_address_hint == LLDB_INVALID_ADDRESS)
+ return false;
+ const unsigned max_iterations = 256;
+ for (unsigned i = 0; i < max_iterations; ++i) {
+ Status st;
+ lldb::addr_t candidate_addr =
+ return_address_hint + i * process.GetAddressByteSize();
+ lldb::addr_t candidate =
+ process.ReadPointerFromMemory(candidate_addr, st);
+ if (st.Fail()) {
+ UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr,
+ st.AsCString());
+ return false;
+ }
+ Address addr;
+ uint32_t permissions;
+ if (process.GetLoadAddressPermissions(candidate, permissions) &&
+ permissions & lldb::ePermissionsExecutable) {
+ address = candidate_addr;
+ UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address);
+ return true;
+ }
+ }
+ UnwindLogMsg("No suitable CFA found");
+ break;
+ }
default:
return false;
}
return false;
}
+lldb::addr_t RegisterContextLLDB::GetReturnAddressHint(int32_t plan_offset) {
+ addr_t hint;
+ if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint))
+ return LLDB_INVALID_ADDRESS;
+ if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
+ return LLDB_INVALID_ADDRESS;
+
+ hint += plan_offset;
+
+ if (auto next = GetNextFrame()) {
+ if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol)
+ return LLDB_INVALID_ADDRESS;
+ if (auto expected_size =
+ next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize(
+ *next->m_sym_ctx.symbol))
+ hint += *expected_size;
+ else {
+ UnwindLogMsgVerbose("Could not retrieve parameter size: %s",
+ llvm::toString(expected_size.takeError()).c_str());
+ return LLDB_INVALID_ADDRESS;
+ }
+ }
+ return hint;
+}
+
// Retrieve a general purpose register value for THIS frame, as saved by the
// NEXT frame, i.e. the frame that
// this frame called. e.g.
@@ -2077,8 +2168,9 @@ void RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) {
}
va_end(args);
- log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
- "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ LLDB_LOGF(log, "%*sth%d/fr%u %s",
+ m_frame_number < 100 ? m_frame_number : 100, "",
+ m_thread.GetIndexID(), m_frame_number, logmsg);
free(logmsg);
}
}
@@ -2098,8 +2190,9 @@ void RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) {
}
va_end(args);
- log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
- "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ LLDB_LOGF(log, "%*sth%d/fr%u %s",
+ m_frame_number < 100 ? m_frame_number : 100, "",
+ m_thread.GetIndexID(), m_frame_number, logmsg);
free(logmsg);
}
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.h b/source/Plugins/Process/Utility/RegisterContextLLDB.h
index 64dd394d233b..114ac35591e7 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -120,6 +120,10 @@ private:
bool IsTrapHandlerSymbol(lldb_private::Process *process,
const lldb_private::SymbolContext &m_sym_ctx) const;
+ /// Check if the given unwind plan indicates a signal trap handler, and
+ /// update frame type and symbol context if so.
+ void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan);
+
// Provide a location for where THIS function saved the CALLER's register
// value
// Or a frame "below" this one saved it, i.e. a function called by this one,
@@ -197,6 +201,8 @@ private:
bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp,
int &valid_pc_offset);
+ lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
+
lldb_private::Thread &m_thread;
///
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 99b897d441b5..db1aa1b8b093 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -109,6 +109,7 @@ RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
switch (register_info->m_target_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
m_reg_info.num_registers = k_num_registers_arm64;
m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
@@ -184,6 +185,7 @@ RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) {
if (IsRegisterSetAvailable(set)) {
switch (m_register_info_up->m_target_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
return &g_reg_sets_arm64[set];
default:
assert(false && "Unhandled target architecture.");
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp
new file mode 100644
index 000000000000..916d3233cde5
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp
@@ -0,0 +1,89 @@
+//===-- RegisterContextWindows_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 "RegisterContextWindows_i386.h"
+#include "RegisterContext_x86.h"
+#include "lldb-x86-register-enums.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+namespace {
+// Declare our g_register_infos structure.
+typedef struct _GPR {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t eip;
+ uint32_t eflags;
+ uint32_t cs;
+ uint32_t fs;
+ uint32_t gs;
+ uint32_t ss;
+ uint32_t ds;
+ uint32_t es;
+} GPR;
+
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
+
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+#reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, \
+ {kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+// clang-format off
+static RegisterInfo g_register_infos_i386[] = {
+// General purpose registers EH_Frame DWARF Generic Process Plugin
+// =========================== ================== ================ ========================= ====================
+ DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+};
+// clang-format on
+} // namespace
+
+RegisterContextWindows_i386::RegisterContextWindows_i386(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch) {
+ assert(target_arch.GetMachine() == llvm::Triple::x86);
+}
+
+const RegisterInfo *RegisterContextWindows_i386::GetRegisterInfo() const {
+ return g_register_infos_i386;
+}
+
+uint32_t RegisterContextWindows_i386::GetRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_i386);
+}
+
+uint32_t RegisterContextWindows_i386::GetUserRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_i386);
+}
+
+size_t RegisterContextWindows_i386::GetGPRSize() const { return sizeof(GPR); }
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_i386.h b/source/Plugins/Process/Utility/RegisterContextWindows_i386.h
new file mode 100644
index 000000000000..7779cc357526
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_i386.h
@@ -0,0 +1,27 @@
+//===-- RegisterContextWindows_i386.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_RegisterContextWindows_i386_H_
+#define liblldb_RegisterContextWindows_i386_H_
+
+#include "RegisterInfoInterface.h"
+
+class RegisterContextWindows_i386 : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterContextWindows_i386(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp
new file mode 100644
index 000000000000..e90584de1a44
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp
@@ -0,0 +1,152 @@
+//===-- RegisterContextWindows_x86_64.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 "RegisterContextWindows_x86_64.h"
+#include "RegisterContext_x86.h"
+#include "lldb-x86-register-enums.h"
+
+#include <vector>
+
+using namespace lldb_private;
+using namespace lldb;
+
+namespace {
+typedef struct _GPR {
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rbx;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint16_t cs;
+ uint16_t fs;
+ uint16_t gs;
+ uint16_t ss;
+ uint16_t ds;
+ uint16_t es;
+} GPR;
+
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+#reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, \
+ {kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+typedef struct _FPReg {
+ XMMReg xmm0;
+ XMMReg xmm1;
+ XMMReg xmm2;
+ XMMReg xmm3;
+ XMMReg xmm4;
+ XMMReg xmm5;
+ XMMReg xmm6;
+ XMMReg xmm7;
+ XMMReg xmm8;
+ XMMReg xmm9;
+ XMMReg xmm10;
+ XMMReg xmm11;
+ XMMReg xmm12;
+ XMMReg xmm13;
+ XMMReg xmm14;
+ XMMReg xmm15;
+} FPReg;
+
+#define FPR_OFFSET(regname) \
+ (sizeof(GPR) + LLVM_EXTENSION offsetof(FPReg, regname))
+
+#define DEFINE_XMM(reg) \
+ { \
+#reg, NULL, sizeof(((FPReg *)nullptr)->reg), FPR_OFFSET(reg), \
+ eEncodingUint, eFormatVectorOfUInt64, \
+ {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+// clang-format off
+static RegisterInfo g_register_infos_x86_64[] = {
+// General purpose registers EH_Frame DWARF Generic Process Plugin
+// =========================== ================== ================ ========================= ====================
+ DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_XMM(xmm0),
+ DEFINE_XMM(xmm1),
+ DEFINE_XMM(xmm2),
+ DEFINE_XMM(xmm3),
+ DEFINE_XMM(xmm4),
+ DEFINE_XMM(xmm5),
+ DEFINE_XMM(xmm6),
+ DEFINE_XMM(xmm7),
+ DEFINE_XMM(xmm8),
+ DEFINE_XMM(xmm9),
+ DEFINE_XMM(xmm10),
+ DEFINE_XMM(xmm11),
+ DEFINE_XMM(xmm12),
+ DEFINE_XMM(xmm13),
+ DEFINE_XMM(xmm14),
+ DEFINE_XMM(xmm15)
+};
+// clang-format on
+} // namespace
+
+RegisterContextWindows_x86_64::RegisterContextWindows_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch) {
+ assert(target_arch.GetMachine() == llvm::Triple::x86_64);
+}
+
+const RegisterInfo *RegisterContextWindows_x86_64::GetRegisterInfo() const {
+ return g_register_infos_x86_64;
+}
+
+uint32_t RegisterContextWindows_x86_64::GetRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_x86_64);
+}
+
+uint32_t RegisterContextWindows_x86_64::GetUserRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_x86_64);
+}
+
+size_t RegisterContextWindows_x86_64::GetGPRSize() const { return sizeof(GPR); }
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h
new file mode 100644
index 000000000000..18198b5b25b3
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h
@@ -0,0 +1,28 @@
+//===-- RegisterContextWindows_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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextWindows_x86_64_H_
+#define liblldb_RegisterContextWindows_x86_64_H_
+
+#include "RegisterInfoInterface.h"
+
+class RegisterContextWindows_x86_64
+ : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterContextWindows_x86_64(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index f7471526d054..8b367bdc6448 100644
--- a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -57,6 +57,7 @@ static const lldb_private::RegisterInfo *
GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
return g_register_infos_arm64_le;
default:
assert(false && "Unhandled target architecture.");
@@ -68,6 +69,7 @@ static uint32_t
GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
sizeof(g_register_infos_arm64_le[0]));
default:
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index 4ee0b528f229..68c12aa6e529 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -456,188 +456,265 @@ static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM};
static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM};
static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
+// Generates register kinds array for 64-bit general purpose registers
+#define GPR64_KIND(reg, generic_kind) \
+ { \
+ arm64_ehframe::reg, arm64_dwarf::reg, generic_kind, LLDB_INVALID_REGNUM, \
+ gpr_##reg \
+ }
+
+// Generates register kinds array for registers with lldb kind
+#define MISC_KIND(lldb_kind) \
+ { \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_kind \
+ }
+
+// Generates register kinds array for vector registers
+#define VREG_KIND(reg) \
+ { \
+ LLDB_INVALID_REGNUM, arm64_dwarf::reg, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpu_##reg \
+ }
+
+// Generates register kinds array for cpsr
+#define CPSR_KIND(lldb_kind) \
+ { \
+ arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, \
+ LLDB_INVALID_REGNUM, lldb_kind \
+ }
+
+#define MISC_GPR_KIND(lldb_kind) CPSR_KIND(lldb_kind)
+#define MISC_FPU_KIND(lldb_kind) MISC_KIND(lldb_kind)
+#define MISC_EXC_KIND(lldb_kind) MISC_KIND(lldb_kind)
+
+// Defines a 64-bit general purpose register
+#define DEFINE_GPR64(reg, generic_kind) \
+ { \
+ #reg, nullptr, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+// Defines a 64-bit general purpose register
+#define DEFINE_GPR64_ALT(reg, alt, generic_kind) \
+ { \
+ #reg, #alt, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+// Defines a 32-bit general purpose pseudo register
+#define DEFINE_GPR32(wreg, xreg) \
+ { \
+ #wreg, nullptr, 4, \
+ GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \
+ lldb::eEncodingUint, lldb::eFormatHex, MISC_KIND(gpr_##wreg), \
+ g_contained_##xreg, g_##wreg##_invalidates, nullptr, 0 \
+ }
+
+// Defines a vector register with 16-byte size
+#define DEFINE_VREG(reg) \
+ { \
+ #reg, nullptr, 16, FPU_OFFSET(fpu_##reg - fpu_v0), lldb::eEncodingVector, \
+ lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, nullptr, \
+ 0 \
+ }
+
+// Defines S and D pseudo registers mapping over correspondig vector register
+#define DEFINE_FPU_PSEUDO(reg, size, offset, vreg) \
+ { \
+ #reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \
+ lldb::eEncodingIEEE754, lldb::eFormatFloat, MISC_KIND(fpu_##reg), \
+ g_contained_##vreg, g_##reg##_invalidates, nullptr, 0 \
+ }
+
+// Defines miscellaneous status and control registers like cpsr, fpsr etc
+#define DEFINE_MISC_REGS(reg, size, TYPE, lldb_kind) \
+ { \
+ #reg, nullptr, size, TYPE##_OFFSET_NAME(reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, MISC_##TYPE##_KIND(lldb_kind), nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
- // clang-format off
- // General purpose registers
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
- // ===== ======= == ============= =================== ================ ================= =============== ======================== =================== ====== ============== ======= ======= ==
- {"x0", nullptr, 8, GPR_OFFSET(0), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x0, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_x0}, nullptr, nullptr, nullptr, 0},
- {"x1", nullptr, 8, GPR_OFFSET(1), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x1, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_x1}, nullptr, nullptr, nullptr, 0},
- {"x2", nullptr, 8, GPR_OFFSET(2), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x2, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_x2}, nullptr, nullptr, nullptr, 0},
- {"x3", nullptr, 8, GPR_OFFSET(3), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x3, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_x3}, nullptr, nullptr, nullptr, 0},
- {"x4", nullptr, 8, GPR_OFFSET(4), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x4, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, gpr_x4}, nullptr, nullptr, nullptr, 0},
- {"x5", nullptr, 8, GPR_OFFSET(5), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x5, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, gpr_x5}, nullptr, nullptr, nullptr, 0},
- {"x6", nullptr, 8, GPR_OFFSET(6), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x6, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, gpr_x6}, nullptr, nullptr, nullptr, 0},
- {"x7", nullptr, 8, GPR_OFFSET(7), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x7, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, gpr_x7}, nullptr, nullptr, nullptr, 0},
- {"x8", nullptr, 8, GPR_OFFSET(8), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x8}, nullptr, nullptr, nullptr, 0},
- {"x9", nullptr, 8, GPR_OFFSET(9), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x9}, nullptr, nullptr, nullptr, 0},
- {"x10", nullptr, 8, GPR_OFFSET(10), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x10}, nullptr, nullptr, nullptr, 0},
- {"x11", nullptr, 8, GPR_OFFSET(11), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x11}, nullptr, nullptr, nullptr, 0},
- {"x12", nullptr, 8, GPR_OFFSET(12), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x12}, nullptr, nullptr, nullptr, 0},
- {"x13", nullptr, 8, GPR_OFFSET(13), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x13}, nullptr, nullptr, nullptr, 0},
- {"x14", nullptr, 8, GPR_OFFSET(14), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x14}, nullptr, nullptr, nullptr, 0},
- {"x15", nullptr, 8, GPR_OFFSET(15), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x15}, nullptr, nullptr, nullptr, 0},
- {"x16", nullptr, 8, GPR_OFFSET(16), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x16}, nullptr, nullptr, nullptr, 0},
- {"x17", nullptr, 8, GPR_OFFSET(17), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x17}, nullptr, nullptr, nullptr, 0},
- {"x18", nullptr, 8, GPR_OFFSET(18), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x18}, nullptr, nullptr, nullptr, 0},
- {"x19", nullptr, 8, GPR_OFFSET(19), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x19}, nullptr, nullptr, nullptr, 0},
- {"x20", nullptr, 8, GPR_OFFSET(20), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x20}, nullptr, nullptr, nullptr, 0},
- {"x21", nullptr, 8, GPR_OFFSET(21), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x21}, nullptr, nullptr, nullptr, 0},
- {"x22", nullptr, 8, GPR_OFFSET(22), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x22}, nullptr, nullptr, nullptr, 0},
- {"x23", nullptr, 8, GPR_OFFSET(23), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x23}, nullptr, nullptr, nullptr, 0},
- {"x24", nullptr, 8, GPR_OFFSET(24), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x24}, nullptr, nullptr, nullptr, 0},
- {"x25", nullptr, 8, GPR_OFFSET(25), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x25}, nullptr, nullptr, nullptr, 0},
- {"x26", nullptr, 8, GPR_OFFSET(26), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x26}, nullptr, nullptr, nullptr, 0},
- {"x27", nullptr, 8, GPR_OFFSET(27), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x27}, nullptr, nullptr, nullptr, 0},
- {"x28", nullptr, 8, GPR_OFFSET(28), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x28}, nullptr, nullptr, nullptr, 0},
- {"fp", "x29", 8, GPR_OFFSET(29), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_fp}, nullptr, nullptr, nullptr, 0},
- {"lr", "x30", 8, GPR_OFFSET(30), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr}, nullptr, nullptr, nullptr, 0},
- {"sp", "x31", 8, GPR_OFFSET(31), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp}, nullptr, nullptr, nullptr, 0},
- {"pc", nullptr, 8, GPR_OFFSET(32), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc}, nullptr, nullptr, nullptr, 0},
-
- {"cpsr",nullptr, 4, GPR_OFFSET_NAME(cpsr), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr}, nullptr, nullptr, nullptr, 0},
-
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE INVALIDATES DYNEXPR SZ
- // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
- {"w0", nullptr, 4, GPR_OFFSET(0) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w0}, g_contained_x0, g_w0_invalidates, nullptr, 0},
- {"w1", nullptr, 4, GPR_OFFSET(1) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w1}, g_contained_x1, g_w1_invalidates, nullptr, 0},
- {"w2", nullptr, 4, GPR_OFFSET(2) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w2}, g_contained_x2, g_w2_invalidates, nullptr, 0},
- {"w3", nullptr, 4, GPR_OFFSET(3) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w3}, g_contained_x3, g_w3_invalidates, nullptr, 0},
- {"w4", nullptr, 4, GPR_OFFSET(4) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w4}, g_contained_x4, g_w4_invalidates, nullptr, 0},
- {"w5", nullptr, 4, GPR_OFFSET(5) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w5}, g_contained_x5, g_w5_invalidates, nullptr, 0},
- {"w6", nullptr, 4, GPR_OFFSET(6) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w6}, g_contained_x6, g_w6_invalidates, nullptr, 0},
- {"w7", nullptr, 4, GPR_OFFSET(7) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w7}, g_contained_x7, g_w7_invalidates, nullptr, 0},
- {"w8", nullptr, 4, GPR_OFFSET(8) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w8}, g_contained_x8, g_w8_invalidates, nullptr, 0},
- {"w9", nullptr, 4, GPR_OFFSET(9) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w9}, g_contained_x9, g_w9_invalidates, nullptr, 0},
- {"w10", nullptr, 4, GPR_OFFSET(10) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w10}, g_contained_x10, g_w10_invalidates, nullptr, 0},
- {"w11", nullptr, 4, GPR_OFFSET(11) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w11}, g_contained_x11, g_w11_invalidates, nullptr, 0},
- {"w12", nullptr, 4, GPR_OFFSET(12) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w12}, g_contained_x12, g_w12_invalidates, nullptr, 0},
- {"w13", nullptr, 4, GPR_OFFSET(13) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w13}, g_contained_x13, g_w13_invalidates, nullptr, 0},
- {"w14", nullptr, 4, GPR_OFFSET(14) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w14}, g_contained_x14, g_w14_invalidates, nullptr, 0},
- {"w15", nullptr, 4, GPR_OFFSET(15) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w15}, g_contained_x15, g_w15_invalidates, nullptr, 0},
- {"w16", nullptr, 4, GPR_OFFSET(16) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w16}, g_contained_x16, g_w16_invalidates, nullptr, 0},
- {"w17", nullptr, 4, GPR_OFFSET(17) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w17}, g_contained_x17, g_w17_invalidates, nullptr, 0},
- {"w18", nullptr, 4, GPR_OFFSET(18) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w18}, g_contained_x18, g_w18_invalidates, nullptr, 0},
- {"w19", nullptr, 4, GPR_OFFSET(19) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w19}, g_contained_x19, g_w19_invalidates, nullptr, 0},
- {"w20", nullptr, 4, GPR_OFFSET(20) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w20}, g_contained_x20, g_w20_invalidates, nullptr, 0},
- {"w21", nullptr, 4, GPR_OFFSET(21) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w21}, g_contained_x21, g_w21_invalidates, nullptr, 0},
- {"w22", nullptr, 4, GPR_OFFSET(22) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w22}, g_contained_x22, g_w22_invalidates, nullptr, 0},
- {"w23", nullptr, 4, GPR_OFFSET(23) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w23}, g_contained_x23, g_w23_invalidates, nullptr, 0},
- {"w24", nullptr, 4, GPR_OFFSET(24) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w24}, g_contained_x24, g_w24_invalidates, nullptr, 0},
- {"w25", nullptr, 4, GPR_OFFSET(25) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w25}, g_contained_x25, g_w25_invalidates, nullptr, 0},
- {"w26", nullptr, 4, GPR_OFFSET(26) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w26}, g_contained_x26, g_w26_invalidates, nullptr, 0},
- {"w27", nullptr, 4, GPR_OFFSET(27) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w27}, g_contained_x27, g_w27_invalidates, nullptr, 0},
- {"w28", nullptr, 4, GPR_OFFSET(28) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w28}, g_contained_x28, g_w28_invalidates, nullptr, 0},
-
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
- // ===== ======= == ============= =================== ================ ================= =============== =================== =================== ====== ============== ======= ======= ==
- {"v0", nullptr, 16, FPU_OFFSET(0), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v0}, nullptr, nullptr, nullptr, 0},
- {"v1", nullptr, 16, FPU_OFFSET(1), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v1}, nullptr, nullptr, nullptr, 0},
- {"v2", nullptr, 16, FPU_OFFSET(2), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v2}, nullptr, nullptr, nullptr, 0},
- {"v3", nullptr, 16, FPU_OFFSET(3), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v3}, nullptr, nullptr, nullptr, 0},
- {"v4", nullptr, 16, FPU_OFFSET(4), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v4}, nullptr, nullptr, nullptr, 0},
- {"v5", nullptr, 16, FPU_OFFSET(5), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v5}, nullptr, nullptr, nullptr, 0},
- {"v6", nullptr, 16, FPU_OFFSET(6), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v6}, nullptr, nullptr, nullptr, 0},
- {"v7", nullptr, 16, FPU_OFFSET(7), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v7}, nullptr, nullptr, nullptr, 0},
- {"v8", nullptr, 16, FPU_OFFSET(8), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v8}, nullptr, nullptr, nullptr, 0},
- {"v9", nullptr, 16, FPU_OFFSET(9), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v9}, nullptr, nullptr, nullptr, 0},
- {"v10", nullptr, 16, FPU_OFFSET(10), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v10}, nullptr, nullptr, nullptr, 0},
- {"v11", nullptr, 16, FPU_OFFSET(11), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v11}, nullptr, nullptr, nullptr, 0},
- {"v12", nullptr, 16, FPU_OFFSET(12), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v12}, nullptr, nullptr, nullptr, 0},
- {"v13", nullptr, 16, FPU_OFFSET(13), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v13}, nullptr, nullptr, nullptr, 0},
- {"v14", nullptr, 16, FPU_OFFSET(14), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v14}, nullptr, nullptr, nullptr, 0},
- {"v15", nullptr, 16, FPU_OFFSET(15), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v15}, nullptr, nullptr, nullptr, 0},
- {"v16", nullptr, 16, FPU_OFFSET(16), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v16}, nullptr, nullptr, nullptr, 0},
- {"v17", nullptr, 16, FPU_OFFSET(17), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v17}, nullptr, nullptr, nullptr, 0},
- {"v18", nullptr, 16, FPU_OFFSET(18), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v18}, nullptr, nullptr, nullptr, 0},
- {"v19", nullptr, 16, FPU_OFFSET(19), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v19}, nullptr, nullptr, nullptr, 0},
- {"v20", nullptr, 16, FPU_OFFSET(20), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v20}, nullptr, nullptr, nullptr, 0},
- {"v21", nullptr, 16, FPU_OFFSET(21), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v21}, nullptr, nullptr, nullptr, 0},
- {"v22", nullptr, 16, FPU_OFFSET(22), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v22}, nullptr, nullptr, nullptr, 0},
- {"v23", nullptr, 16, FPU_OFFSET(23), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v23}, nullptr, nullptr, nullptr, 0},
- {"v24", nullptr, 16, FPU_OFFSET(24), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v24}, nullptr, nullptr, nullptr, 0},
- {"v25", nullptr, 16, FPU_OFFSET(25), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v25}, nullptr, nullptr, nullptr, 0},
- {"v26", nullptr, 16, FPU_OFFSET(26), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v26}, nullptr, nullptr, nullptr, 0},
- {"v27", nullptr, 16, FPU_OFFSET(27), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v27}, nullptr, nullptr, nullptr, 0},
- {"v28", nullptr, 16, FPU_OFFSET(28), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v28}, nullptr, nullptr, nullptr, 0},
- {"v29", nullptr, 16, FPU_OFFSET(29), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v29}, nullptr, nullptr, nullptr, 0},
- {"v30", nullptr, 16, FPU_OFFSET(30), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v30}, nullptr, nullptr, nullptr, 0},
- {"v31", nullptr, 16, FPU_OFFSET(31), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v31}, nullptr, nullptr, nullptr, 0},
-
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATES DYNEXPR SZ
- // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
- {"s0", nullptr, 4, FPU_OFFSET(0) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0}, g_contained_v0, g_s0_invalidates, nullptr, 0},
- {"s1", nullptr, 4, FPU_OFFSET(1) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1}, g_contained_v1, g_s1_invalidates, nullptr, 0},
- {"s2", nullptr, 4, FPU_OFFSET(2) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2}, g_contained_v2, g_s2_invalidates, nullptr, 0},
- {"s3", nullptr, 4, FPU_OFFSET(3) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3}, g_contained_v3, g_s3_invalidates, nullptr, 0},
- {"s4", nullptr, 4, FPU_OFFSET(4) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4}, g_contained_v4, g_s4_invalidates, nullptr, 0},
- {"s5", nullptr, 4, FPU_OFFSET(5) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5}, g_contained_v5, g_s5_invalidates, nullptr, 0},
- {"s6", nullptr, 4, FPU_OFFSET(6) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6}, g_contained_v6, g_s6_invalidates, nullptr, 0},
- {"s7", nullptr, 4, FPU_OFFSET(7) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7}, g_contained_v7, g_s7_invalidates, nullptr, 0},
- {"s8", nullptr, 4, FPU_OFFSET(8) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8}, g_contained_v8, g_s8_invalidates, nullptr, 0},
- {"s9", nullptr, 4, FPU_OFFSET(9) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9}, g_contained_v9, g_s9_invalidates, nullptr, 0},
- {"s10", nullptr, 4, FPU_OFFSET(10) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10}, g_contained_v10, g_s10_invalidates, nullptr, 0},
- {"s11", nullptr, 4, FPU_OFFSET(11) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11}, g_contained_v11, g_s11_invalidates, nullptr, 0},
- {"s12", nullptr, 4, FPU_OFFSET(12) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12}, g_contained_v12, g_s12_invalidates, nullptr, 0},
- {"s13", nullptr, 4, FPU_OFFSET(13) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13}, g_contained_v13, g_s13_invalidates, nullptr, 0},
- {"s14", nullptr, 4, FPU_OFFSET(14) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14}, g_contained_v14, g_s14_invalidates, nullptr, 0},
- {"s15", nullptr, 4, FPU_OFFSET(15) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15}, g_contained_v15, g_s15_invalidates, nullptr, 0},
- {"s16", nullptr, 4, FPU_OFFSET(16) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16}, g_contained_v16, g_s16_invalidates, nullptr, 0},
- {"s17", nullptr, 4, FPU_OFFSET(17) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17}, g_contained_v17, g_s17_invalidates, nullptr, 0},
- {"s18", nullptr, 4, FPU_OFFSET(18) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18}, g_contained_v18, g_s18_invalidates, nullptr, 0},
- {"s19", nullptr, 4, FPU_OFFSET(19) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19}, g_contained_v19, g_s19_invalidates, nullptr, 0},
- {"s20", nullptr, 4, FPU_OFFSET(20) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20}, g_contained_v20, g_s20_invalidates, nullptr, 0},
- {"s21", nullptr, 4, FPU_OFFSET(21) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21}, g_contained_v21, g_s21_invalidates, nullptr, 0},
- {"s22", nullptr, 4, FPU_OFFSET(22) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22}, g_contained_v22, g_s22_invalidates, nullptr, 0},
- {"s23", nullptr, 4, FPU_OFFSET(23) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23}, g_contained_v23, g_s23_invalidates, nullptr, 0},
- {"s24", nullptr, 4, FPU_OFFSET(24) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24}, g_contained_v24, g_s24_invalidates, nullptr, 0},
- {"s25", nullptr, 4, FPU_OFFSET(25) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25}, g_contained_v25, g_s25_invalidates, nullptr, 0},
- {"s26", nullptr, 4, FPU_OFFSET(26) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26}, g_contained_v26, g_s26_invalidates, nullptr, 0},
- {"s27", nullptr, 4, FPU_OFFSET(27) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27}, g_contained_v27, g_s27_invalidates, nullptr, 0},
- {"s28", nullptr, 4, FPU_OFFSET(28) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28}, g_contained_v28, g_s28_invalidates, nullptr, 0},
- {"s29", nullptr, 4, FPU_OFFSET(29) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29}, g_contained_v29, g_s29_invalidates, nullptr, 0},
- {"s30", nullptr, 4, FPU_OFFSET(30) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30}, g_contained_v30, g_s30_invalidates, nullptr, 0},
- {"s31", nullptr, 4, FPU_OFFSET(31) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31}, g_contained_v31, g_s31_invalidates, nullptr, 0},
-
- {"d0", nullptr, 8, FPU_OFFSET(0) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d0}, g_contained_v0, g_d0_invalidates, nullptr, 0},
- {"d1", nullptr, 8, FPU_OFFSET(1) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d1}, g_contained_v1, g_d1_invalidates, nullptr, 0},
- {"d2", nullptr, 8, FPU_OFFSET(2) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d2}, g_contained_v2, g_d2_invalidates, nullptr, 0},
- {"d3", nullptr, 8, FPU_OFFSET(3) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d3}, g_contained_v3, g_d3_invalidates, nullptr, 0},
- {"d4", nullptr, 8, FPU_OFFSET(4) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d4}, g_contained_v4, g_d4_invalidates, nullptr, 0},
- {"d5", nullptr, 8, FPU_OFFSET(5) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d5}, g_contained_v5, g_d5_invalidates, nullptr, 0},
- {"d6", nullptr, 8, FPU_OFFSET(6) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d6}, g_contained_v6, g_d6_invalidates, nullptr, 0},
- {"d7", nullptr, 8, FPU_OFFSET(7) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d7}, g_contained_v7, g_d7_invalidates, nullptr, 0},
- {"d8", nullptr, 8, FPU_OFFSET(8) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d8}, g_contained_v8, g_d8_invalidates, nullptr, 0},
- {"d9", nullptr, 8, FPU_OFFSET(9) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d9}, g_contained_v9, g_d9_invalidates, nullptr, 0},
- {"d10", nullptr, 8, FPU_OFFSET(10) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d10}, g_contained_v10, g_d10_invalidates, nullptr, 0},
- {"d11", nullptr, 8, FPU_OFFSET(11) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d11}, g_contained_v11, g_d11_invalidates, nullptr, 0},
- {"d12", nullptr, 8, FPU_OFFSET(12) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d12}, g_contained_v12, g_d12_invalidates, nullptr, 0},
- {"d13", nullptr, 8, FPU_OFFSET(13) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d13}, g_contained_v13, g_d13_invalidates, nullptr, 0},
- {"d14", nullptr, 8, FPU_OFFSET(14) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d14}, g_contained_v14, g_d14_invalidates, nullptr, 0},
- {"d15", nullptr, 8, FPU_OFFSET(15) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d15}, g_contained_v15, g_d15_invalidates, nullptr, 0},
- {"d16", nullptr, 8, FPU_OFFSET(16) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d16}, g_contained_v16, g_d16_invalidates, nullptr, 0},
- {"d17", nullptr, 8, FPU_OFFSET(17) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d17}, g_contained_v17, g_d17_invalidates, nullptr, 0},
- {"d18", nullptr, 8, FPU_OFFSET(18) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d18}, g_contained_v18, g_d18_invalidates, nullptr, 0},
- {"d19", nullptr, 8, FPU_OFFSET(19) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d19}, g_contained_v19, g_d19_invalidates, nullptr, 0},
- {"d20", nullptr, 8, FPU_OFFSET(20) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d20}, g_contained_v20, g_d20_invalidates, nullptr, 0},
- {"d21", nullptr, 8, FPU_OFFSET(21) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d21}, g_contained_v21, g_d21_invalidates, nullptr, 0},
- {"d22", nullptr, 8, FPU_OFFSET(22) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d22}, g_contained_v22, g_d22_invalidates, nullptr, 0},
- {"d23", nullptr, 8, FPU_OFFSET(23) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d23}, g_contained_v23, g_d23_invalidates, nullptr, 0},
- {"d24", nullptr, 8, FPU_OFFSET(24) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d24}, g_contained_v24, g_d24_invalidates, nullptr, 0},
- {"d25", nullptr, 8, FPU_OFFSET(25) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d25}, g_contained_v25, g_d25_invalidates, nullptr, 0},
- {"d26", nullptr, 8, FPU_OFFSET(26) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d26}, g_contained_v26, g_d26_invalidates, nullptr, 0},
- {"d27", nullptr, 8, FPU_OFFSET(27) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d27}, g_contained_v27, g_d27_invalidates, nullptr, 0},
- {"d28", nullptr, 8, FPU_OFFSET(28) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d28}, g_contained_v28, g_d28_invalidates, nullptr, 0},
- {"d29", nullptr, 8, FPU_OFFSET(29) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d29}, g_contained_v29, g_d29_invalidates, nullptr, 0},
- {"d30", nullptr, 8, FPU_OFFSET(30) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d30}, g_contained_v30, g_d30_invalidates, nullptr, 0},
- {"d31", nullptr, 8, FPU_OFFSET(31) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d31}, g_contained_v31, g_d31_invalidates, nullptr, 0},
-
- {"fpsr", nullptr, 4, FPU_OFFSET_NAME(fpsr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr}, nullptr, nullptr, nullptr, 0},
- {"fpcr", nullptr, 4, FPU_OFFSET_NAME(fpcr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr}, nullptr, nullptr, nullptr, 0},
-
- {"far", nullptr, 8, EXC_OFFSET_NAME(far), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, nullptr, 0},
- {"esr", nullptr, 4, EXC_OFFSET_NAME(esr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr}, nullptr, nullptr, nullptr, 0},
- {"exception", nullptr, 4, EXC_OFFSET_NAME(exception), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, nullptr, 0},
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GPR64(x1, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GPR64(x2, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GPR64(x3, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GPR64(x4, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GPR64(x5, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GPR64(x6, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GPR64(x7, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_GPR64(x8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x9, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x10, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x11, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x12, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x13, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x14, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x15, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x16, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x17, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x18, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x19, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x20, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x21, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x22, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x23, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x24, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x25, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x26, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x27, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x28, LLDB_INVALID_REGNUM),
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64_ALT(fp, x29, LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GPR64_ALT(lr, x30, LLDB_REGNUM_GENERIC_RA),
+ DEFINE_GPR64_ALT(sp, x31, LLDB_REGNUM_GENERIC_SP),
+ DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(cpsr, 4, GPR, gpr_cpsr),
+
+ // DEFINE_GPR32(name, parent name)
+ DEFINE_GPR32(w0, x0),
+ DEFINE_GPR32(w1, x1),
+ DEFINE_GPR32(w2, x2),
+ DEFINE_GPR32(w3, x3),
+ DEFINE_GPR32(w4, x4),
+ DEFINE_GPR32(w5, x5),
+ DEFINE_GPR32(w6, x6),
+ DEFINE_GPR32(w7, x7),
+ DEFINE_GPR32(w8, x8),
+ DEFINE_GPR32(w9, x9),
+ DEFINE_GPR32(w10, x10),
+ DEFINE_GPR32(w11, x11),
+ DEFINE_GPR32(w12, x12),
+ DEFINE_GPR32(w13, x13),
+ DEFINE_GPR32(w14, x14),
+ DEFINE_GPR32(w15, x15),
+ DEFINE_GPR32(w16, x16),
+ DEFINE_GPR32(w17, x17),
+ DEFINE_GPR32(w18, x18),
+ DEFINE_GPR32(w19, x19),
+ DEFINE_GPR32(w20, x20),
+ DEFINE_GPR32(w21, x21),
+ DEFINE_GPR32(w22, x22),
+ DEFINE_GPR32(w23, x23),
+ DEFINE_GPR32(w24, x24),
+ DEFINE_GPR32(w25, x25),
+ DEFINE_GPR32(w26, x26),
+ DEFINE_GPR32(w27, x27),
+ DEFINE_GPR32(w28, x28),
+
+ // DEFINE_VREG(name)
+ DEFINE_VREG(v0),
+ DEFINE_VREG(v1),
+ DEFINE_VREG(v2),
+ DEFINE_VREG(v3),
+ DEFINE_VREG(v4),
+ DEFINE_VREG(v5),
+ DEFINE_VREG(v6),
+ DEFINE_VREG(v7),
+ DEFINE_VREG(v8),
+ DEFINE_VREG(v9),
+ DEFINE_VREG(v10),
+ DEFINE_VREG(v11),
+ DEFINE_VREG(v12),
+ DEFINE_VREG(v13),
+ DEFINE_VREG(v14),
+ DEFINE_VREG(v15),
+ DEFINE_VREG(v16),
+ DEFINE_VREG(v17),
+ DEFINE_VREG(v18),
+ DEFINE_VREG(v19),
+ DEFINE_VREG(v20),
+ DEFINE_VREG(v21),
+ DEFINE_VREG(v22),
+ DEFINE_VREG(v23),
+ DEFINE_VREG(v24),
+ DEFINE_VREG(v25),
+ DEFINE_VREG(v26),
+ DEFINE_VREG(v27),
+ DEFINE_VREG(v28),
+ DEFINE_VREG(v29),
+ DEFINE_VREG(v30),
+ DEFINE_VREG(v31),
+
+ // DEFINE_FPU_PSEUDO(name, size, ENDIAN OFFSET, parent register)
+ DEFINE_FPU_PSEUDO(s0, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v0),
+ DEFINE_FPU_PSEUDO(s1, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v1),
+ DEFINE_FPU_PSEUDO(s2, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v2),
+ DEFINE_FPU_PSEUDO(s3, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v3),
+ DEFINE_FPU_PSEUDO(s4, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v4),
+ DEFINE_FPU_PSEUDO(s5, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v5),
+ DEFINE_FPU_PSEUDO(s6, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v6),
+ DEFINE_FPU_PSEUDO(s7, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v7),
+ DEFINE_FPU_PSEUDO(s8, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v8),
+ DEFINE_FPU_PSEUDO(s9, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v9),
+ DEFINE_FPU_PSEUDO(s10, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v10),
+ DEFINE_FPU_PSEUDO(s11, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v11),
+ DEFINE_FPU_PSEUDO(s12, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v12),
+ DEFINE_FPU_PSEUDO(s13, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v13),
+ DEFINE_FPU_PSEUDO(s14, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v14),
+ DEFINE_FPU_PSEUDO(s15, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v15),
+ DEFINE_FPU_PSEUDO(s16, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v16),
+ DEFINE_FPU_PSEUDO(s17, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v17),
+ DEFINE_FPU_PSEUDO(s18, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v18),
+ DEFINE_FPU_PSEUDO(s19, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v19),
+ DEFINE_FPU_PSEUDO(s20, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v20),
+ DEFINE_FPU_PSEUDO(s21, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v21),
+ DEFINE_FPU_PSEUDO(s22, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v22),
+ DEFINE_FPU_PSEUDO(s23, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v23),
+ DEFINE_FPU_PSEUDO(s24, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v24),
+ DEFINE_FPU_PSEUDO(s25, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v25),
+ DEFINE_FPU_PSEUDO(s26, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v26),
+ DEFINE_FPU_PSEUDO(s27, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v27),
+ DEFINE_FPU_PSEUDO(s28, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v28),
+ DEFINE_FPU_PSEUDO(s29, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v29),
+ DEFINE_FPU_PSEUDO(s30, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v30),
+ DEFINE_FPU_PSEUDO(s31, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v31),
+
+ DEFINE_FPU_PSEUDO(d0, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v0),
+ DEFINE_FPU_PSEUDO(d1, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v1),
+ DEFINE_FPU_PSEUDO(d2, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v2),
+ DEFINE_FPU_PSEUDO(d3, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v3),
+ DEFINE_FPU_PSEUDO(d4, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v4),
+ DEFINE_FPU_PSEUDO(d5, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v5),
+ DEFINE_FPU_PSEUDO(d6, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v6),
+ DEFINE_FPU_PSEUDO(d7, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v7),
+ DEFINE_FPU_PSEUDO(d8, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v8),
+ DEFINE_FPU_PSEUDO(d9, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v9),
+ DEFINE_FPU_PSEUDO(d10, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v10),
+ DEFINE_FPU_PSEUDO(d11, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v11),
+ DEFINE_FPU_PSEUDO(d12, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v12),
+ DEFINE_FPU_PSEUDO(d13, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v13),
+ DEFINE_FPU_PSEUDO(d14, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v14),
+ DEFINE_FPU_PSEUDO(d15, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v15),
+ DEFINE_FPU_PSEUDO(d16, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v16),
+ DEFINE_FPU_PSEUDO(d17, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v17),
+ DEFINE_FPU_PSEUDO(d18, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v18),
+ DEFINE_FPU_PSEUDO(d19, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v19),
+ DEFINE_FPU_PSEUDO(d20, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v20),
+ DEFINE_FPU_PSEUDO(d21, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v21),
+ DEFINE_FPU_PSEUDO(d22, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v22),
+ DEFINE_FPU_PSEUDO(d23, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v23),
+ DEFINE_FPU_PSEUDO(d24, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v24),
+ DEFINE_FPU_PSEUDO(d25, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v25),
+ DEFINE_FPU_PSEUDO(d26, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v26),
+ DEFINE_FPU_PSEUDO(d27, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v27),
+ DEFINE_FPU_PSEUDO(d28, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v28),
+ DEFINE_FPU_PSEUDO(d29, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v29),
+ DEFINE_FPU_PSEUDO(d30, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v30),
+ DEFINE_FPU_PSEUDO(d31, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v31),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(fpsr, 4, FPU, fpu_fpsr),
+ DEFINE_MISC_REGS(fpcr, 4, FPU, fpu_fpcr),
+ DEFINE_MISC_REGS(far, 8, EXC, exc_far),
+ DEFINE_MISC_REGS(esr, 4, EXC, exc_esr),
+ DEFINE_MISC_REGS(exception, 4, EXC, exc_exception),
{DEFINE_DBG(bvr, 0)},
{DEFINE_DBG(bvr, 1)},
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 588015a51ef1..6d03bd534f37 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -30,331 +30,266 @@ using namespace lldb;
using namespace lldb_private;
const char *StopInfoMachException::GetDescription() {
- if (m_description.empty() && m_value != 0) {
- ExecutionContext exe_ctx(m_thread_wp.lock());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu =
- target ? target->GetArchitecture().GetMachine()
- : llvm::Triple::UnknownArch;
-
- const char *exc_desc = nullptr;
- const char *code_label = "code";
- const char *code_desc = nullptr;
- const char *subcode_label = "subcode";
- const char *subcode_desc = nullptr;
+ if (!m_description.empty())
+ return m_description.c_str();
+ if (GetValue() == eStopReasonInvalid)
+ return "invalid stop reason!";
+
+ ExecutionContext exe_ctx(m_thread_wp.lock());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ const char *exc_desc = nullptr;
+ const char *code_label = "code";
+ const char *code_desc = nullptr;
+ const char *subcode_label = "subcode";
+ const char *subcode_desc = nullptr;
#if defined(__APPLE__)
- char code_desc_buf[32];
- char subcode_desc_buf[32];
+ char code_desc_buf[32];
+ char subcode_desc_buf[32];
#endif
- switch (m_value) {
- case 1: // EXC_BAD_ACCESS
- exc_desc = "EXC_BAD_ACCESS";
- subcode_label = "address";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code) {
- case 0xd:
- code_desc = "EXC_I386_GPFLT";
- m_exc_data_count = 1;
- break;
- }
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code) {
- case 0x101:
- code_desc = "EXC_ARM_DA_ALIGN";
- break;
- case 0x102:
- code_desc = "EXC_ARM_DA_DEBUG";
- break;
- }
+ switch (m_value) {
+ case 1: // EXC_BAD_ACCESS
+ exc_desc = "EXC_BAD_ACCESS";
+ subcode_label = "address";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 0xd:
+ code_desc = "EXC_I386_GPFLT";
+ m_exc_data_count = 1;
break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 0x101:
- code_desc = "EXC_PPC_VM_PROT_READ";
- break;
- case 0x102:
- code_desc = "EXC_PPC_BADSPACE";
- break;
- case 0x103:
- code_desc = "EXC_PPC_UNALIGNED";
- break;
- }
+ }
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
break;
-
- default:
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
break;
}
break;
- case 2: // EXC_BAD_INSTRUCTION
- exc_desc = "EXC_BAD_INSTRUCTION";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (m_exc_code == 1)
- code_desc = "EXC_I386_INVOP";
- break;
+ default:
+ break;
+ }
+ break;
+
+ case 2: // EXC_BAD_INSTRUCTION
+ exc_desc = "EXC_BAD_INSTRUCTION";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (m_exc_code == 1)
+ code_desc = "EXC_I386_INVOP";
+ break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_PPC_INVALID_SYSCALL";
- break;
- case 2:
- code_desc = "EXC_PPC_UNIPL_INST";
- break;
- case 3:
- code_desc = "EXC_PPC_PRIVINST";
- break;
- case 4:
- code_desc = "EXC_PPC_PRIVREG";
- break;
- case 5:
- code_desc = "EXC_PPC_TRACE";
- break;
- case 6:
- code_desc = "EXC_PPC_PERFMON";
- break;
- }
- break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (m_exc_code == 1)
+ code_desc = "EXC_ARM_UNDEFINED";
+ break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (m_exc_code == 1)
- code_desc = "EXC_ARM_UNDEFINED";
+ default:
+ break;
+ }
+ break;
+
+ case 3: // EXC_ARITHMETIC
+ exc_desc = "EXC_ARITHMETIC";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_DIV";
break;
-
- default:
+ case 2:
+ code_desc = "EXC_I386_INTO";
break;
- }
- break;
-
- case 3: // EXC_ARITHMETIC
- exc_desc = "EXC_ARITHMETIC";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_I386_DIV";
- break;
- case 2:
- code_desc = "EXC_I386_INTO";
- break;
- case 3:
- code_desc = "EXC_I386_NOEXT";
- break;
- case 4:
- code_desc = "EXC_I386_EXTOVR";
- break;
- case 5:
- code_desc = "EXC_I386_EXTERR";
- break;
- case 6:
- code_desc = "EXC_I386_EMERR";
- break;
- case 7:
- code_desc = "EXC_I386_BOUND";
- break;
- case 8:
- code_desc = "EXC_I386_SSEEXTERR";
- break;
- }
+ case 3:
+ code_desc = "EXC_I386_NOEXT";
break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_PPC_OVERFLOW";
- break;
- case 2:
- code_desc = "EXC_PPC_ZERO_DIVIDE";
- break;
- case 3:
- code_desc = "EXC_PPC_FLT_INEXACT";
- break;
- case 4:
- code_desc = "EXC_PPC_FLT_ZERO_DIVIDE";
- break;
- case 5:
- code_desc = "EXC_PPC_FLT_UNDERFLOW";
- break;
- case 6:
- code_desc = "EXC_PPC_FLT_OVERFLOW";
- break;
- case 7:
- code_desc = "EXC_PPC_FLT_NOT_A_NUMBER";
- break;
- }
+ case 4:
+ code_desc = "EXC_I386_EXTOVR";
break;
-
- default:
+ case 5:
+ code_desc = "EXC_I386_EXTERR";
+ break;
+ case 6:
+ code_desc = "EXC_I386_EMERR";
+ break;
+ case 7:
+ code_desc = "EXC_I386_BOUND";
+ break;
+ case 8:
+ code_desc = "EXC_I386_SSEEXTERR";
break;
}
break;
- case 4: // EXC_EMULATION
- exc_desc = "EXC_EMULATION";
+ default:
break;
+ }
+ break;
- case 5: // EXC_SOFTWARE
- exc_desc = "EXC_SOFTWARE";
- if (m_exc_code == 0x10003) {
- subcode_desc = "EXC_SOFT_SIGNAL";
- subcode_label = "signo";
+ case 4: // EXC_EMULATION
+ exc_desc = "EXC_EMULATION";
+ break;
+
+ case 5: // EXC_SOFTWARE
+ exc_desc = "EXC_SOFTWARE";
+ if (m_exc_code == 0x10003) {
+ subcode_desc = "EXC_SOFT_SIGNAL";
+ subcode_label = "signo";
+ }
+ break;
+
+ case 6: // EXC_BREAKPOINT
+ {
+ exc_desc = "EXC_BREAKPOINT";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_SGL";
+ break;
+ case 2:
+ code_desc = "EXC_I386_BPT";
+ break;
}
break;
- case 6: // EXC_BREAKPOINT
- {
- exc_desc = "EXC_BREAKPOINT";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_I386_SGL";
- break;
- case 2:
- code_desc = "EXC_I386_BPT";
- break;
- }
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_PPC_BREAKPOINT";
- break;
- }
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code) {
- case 0x101:
- code_desc = "EXC_ARM_DA_ALIGN";
- break;
- case 0x102:
- code_desc = "EXC_ARM_DA_DEBUG";
- break;
- case 1:
- code_desc = "EXC_ARM_BREAKPOINT";
- break;
- // FIXME temporary workaround, exc_code 0 does not really mean
- // EXC_ARM_BREAKPOINT
- case 0:
- code_desc = "EXC_ARM_BREAKPOINT";
- break;
- }
+ case 1:
+ code_desc = "EXC_ARM_BREAKPOINT";
break;
-
- default:
+ // FIXME temporary workaround, exc_code 0 does not really mean
+ // EXC_ARM_BREAKPOINT
+ case 0:
+ code_desc = "EXC_ARM_BREAKPOINT";
break;
}
- } break;
-
- case 7:
- exc_desc = "EXC_SYSCALL";
break;
- case 8:
- exc_desc = "EXC_MACH_SYSCALL";
+ default:
break;
+ }
+ } break;
- case 9:
- exc_desc = "EXC_RPC_ALERT";
- break;
+ case 7:
+ exc_desc = "EXC_SYSCALL";
+ break;
- case 10:
- exc_desc = "EXC_CRASH";
- break;
- case 11:
- exc_desc = "EXC_RESOURCE";
+ case 8:
+ exc_desc = "EXC_MACH_SYSCALL";
+ break;
+
+ case 9:
+ exc_desc = "EXC_RPC_ALERT";
+ break;
+
+ case 10:
+ exc_desc = "EXC_CRASH";
+ break;
+ case 11:
+ exc_desc = "EXC_RESOURCE";
#if defined(__APPLE__)
- {
- int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);
-
- code_label = "limit";
- code_desc = code_desc_buf;
- subcode_label = "observed";
- subcode_desc = subcode_desc_buf;
-
- switch (resource_type) {
- case RESOURCE_TYPE_CPU:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
- (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
- snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
- (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode));
- break;
- case RESOURCE_TYPE_WAKEUPS:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s",
+ {
+ int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);
+
+ code_label = "limit";
+ code_desc = code_desc_buf;
+ subcode_label = "observed";
+ subcode_desc = subcode_desc_buf;
+
+ switch (resource_type) {
+ case RESOURCE_TYPE_CPU:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(
+ m_exc_subcode));
+ break;
+ case RESOURCE_TYPE_WAKEUPS:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS";
+ snprintf(
+ code_desc_buf, sizeof(code_desc_buf), "%d w/s",
(int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code));
- snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
- (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode));
- break;
- case RESOURCE_TYPE_MEMORY:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
- (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
- subcode_desc = nullptr;
- subcode_label = "unused";
- break;
- case RESOURCE_TYPE_IO:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
- (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
- snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
- (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));;
- break;
- }
- }
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(
+ m_exc_subcode));
+ break;
+ case RESOURCE_TYPE_MEMORY:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
+ subcode_desc = nullptr;
+ subcode_label = "unused";
+ break;
+#if defined(RESOURCE_TYPE_IO)
+ // RESOURCE_TYPE_IO is introduced in macOS SDK 10.12.
+ case RESOURCE_TYPE_IO:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));
+ ;
+ break;
#endif
- break;
- case 12:
- exc_desc = "EXC_GUARD";
- break;
+ }
}
+#endif
+ break;
+ case 12:
+ exc_desc = "EXC_GUARD";
+ break;
+ }
- StreamString strm;
+ StreamString strm;
- if (exc_desc)
- strm.PutCString(exc_desc);
- else
- strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
+ if (exc_desc)
+ strm.PutCString(exc_desc);
+ else
+ strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
- if (m_exc_data_count >= 1) {
- if (code_desc)
- strm.Printf(" (%s=%s", code_label, code_desc);
- else
- strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
- }
+ if (m_exc_data_count >= 1) {
+ if (code_desc)
+ strm.Printf(" (%s=%s", code_label, code_desc);
+ else
+ strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
+ }
- if (m_exc_data_count >= 2) {
- if (subcode_desc)
- strm.Printf(", %s=%s", subcode_label, subcode_desc);
- else
- strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
- }
+ if (m_exc_data_count >= 2) {
+ if (subcode_desc)
+ strm.Printf(", %s=%s", subcode_label, subcode_desc);
+ else
+ strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
+ }
- if (m_exc_data_count > 0)
- strm.PutChar(')');
+ if (m_exc_data_count > 0)
+ strm.PutChar(')');
- m_description = strm.GetString();
- }
+ m_description = strm.GetString();
return m_description.c_str();
}
@@ -362,141 +297,62 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
bool pc_already_adjusted, bool adjust_pc_if_needed) {
- if (exc_type != 0) {
- uint32_t pc_decrement = 0;
- ExecutionContext exe_ctx(thread.shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu =
- target ? target->GetArchitecture().GetMachine()
- : llvm::Triple::UnknownArch;
-
- switch (exc_type) {
- case 1: // EXC_BAD_ACCESS
- break;
-
- case 2: // EXC_BAD_INSTRUCTION
- switch (cpu) {
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (exc_code) {
- case 1: // EXC_PPC_INVALID_SYSCALL
- case 2: // EXC_PPC_UNIPL_INST
- case 3: // EXC_PPC_PRIVINST
- case 4: // EXC_PPC_PRIVREG
- break;
- case 5: // EXC_PPC_TRACE
- return StopInfo::CreateStopReasonToTrace(thread);
- case 6: // EXC_PPC_PERFMON
- break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 3: // EXC_ARITHMETIC
- case 4: // EXC_EMULATION
- break;
-
- case 5: // EXC_SOFTWARE
- if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
- {
- if (exc_sub_code == 5) {
- // On MacOSX, a SIGTRAP can signify that a process has called exec,
- // so we should check with our dynamic loader to verify.
- ProcessSP process_sp(thread.GetProcess());
- if (process_sp) {
- DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
- if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
- // The program was re-exec'ed
- return StopInfo::CreateStopReasonWithExec(thread);
- }
- // if (!process_did_exec)
- // {
- // // We have a SIGTRAP, make sure we
- // didn't exec by checking
- // // for the PC being at
- // "_dyld_start"...
- // lldb::StackFrameSP frame_sp
- // (thread.GetStackFrameAtIndex(0));
- // if (frame_sp)
- // {
- // const Symbol *symbol =
- // frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- // if (symbol)
- // {
- // if (symbol->GetName() ==
- // ConstString("_dyld_start"))
- // process_did_exec = true;
- // }
- // }
- // }
+ if (exc_type == 0)
+ return StopInfoSP();
+
+ uint32_t pc_decrement = 0;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ switch (exc_type) {
+ case 1: // EXC_BAD_ACCESS
+ case 2: // EXC_BAD_INSTRUCTION
+ case 3: // EXC_ARITHMETIC
+ case 4: // EXC_EMULATION
+ break;
+
+ case 5: // EXC_SOFTWARE
+ if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
+ {
+ if (exc_sub_code == 5) {
+ // On MacOSX, a SIGTRAP can signify that a process has called exec,
+ // so we should check with our dynamic loader to verify.
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
+ if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
+ // The program was re-exec'ed
+ return StopInfo::CreateStopReasonWithExec(thread);
}
}
- return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
}
- break;
-
- case 6: // EXC_BREAKPOINT
- {
- bool is_actual_breakpoint = false;
- bool is_trace_if_actual_breakpoint_missing = false;
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (exc_code == 1) // EXC_I386_SGL
- {
- if (!exc_sub_code) {
- // This looks like a plain trap.
- // Have to check if there is a breakpoint here as well. When you
- // single-step onto a trap, the single step stops you not to trap.
- // Since we also do that check below, let's just use that logic.
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- } else {
-
- // It's a watchpoint, then.
- // The exc_sub_code indicates the data break address.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress(
- (lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled()) {
- // Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data. Set the hardware index if
- // that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread,
- wp_sp->GetID());
- }
- }
- } else if (exc_code == 2 || // EXC_I386_BPT
- exc_code == 3) // EXC_I386_BPTFLT
- {
- // KDP returns EXC_I386_BPTFLT for trace breakpoints
- if (exc_code == 3)
- is_trace_if_actual_breakpoint_missing = true;
-
+ return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
+ }
+ break;
+
+ case 6: // EXC_BREAKPOINT
+ {
+ bool is_actual_breakpoint = false;
+ bool is_trace_if_actual_breakpoint_missing = false;
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (exc_code == 1) // EXC_I386_SGL
+ {
+ if (!exc_sub_code) {
+ // This looks like a plain trap.
+ // Have to check if there is a breakpoint here as well. When you
+ // single-step onto a trap, the single step stops you not to trap.
+ // Since we also do that check below, let's just use that logic.
is_actual_breakpoint = true;
- if (!pc_already_adjusted)
- pc_decrement = 1;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
- break;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else {
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a
- // known/enabled data break address from our watchpoint list.
+ // It's a watchpoint, then.
+ // The exc_sub_code indicates the data break address.
lldb::WatchpointSP wp_sp;
if (target)
wp_sp = target->GetWatchpointList().FindByAddress(
@@ -509,116 +365,148 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread,
wp_sp->GetID());
- } else {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
}
- } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
- // is currently returning this so accept it
- // as indicating a breakpoint until the
- // kernel is fixed
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
}
- break;
+ } else if (exc_code == 2 || // EXC_I386_BPT
+ exc_code == 3) // EXC_I386_BPTFLT
+ {
+ // KDP returns EXC_I386_BPTFLT for trace breakpoints
+ if (exc_code == 3)
+ is_trace_if_actual_breakpoint_missing = true;
- case llvm::Triple::aarch64: {
- if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
- {
- // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
- // is set
- is_actual_breakpoint = false;
+ is_actual_breakpoint = true;
+ if (!pc_already_adjusted)
+ pc_decrement = 1;
+ }
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled data break address from our watchpoint list.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data. Set the hardware index if
+ // that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
+ } else {
+ is_actual_breakpoint = true;
is_trace_if_actual_breakpoint_missing = true;
}
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a
- // known/enabled data break address from our watchpoint list.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress(
- (lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled()) {
- // Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data. Set the hardware index if
- // that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread,
- wp_sp->GetID());
- }
- // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
- // EXC_BAD_ACCESS
- if (thread.GetTemporaryResumeState() == eStateStepping)
- return StopInfo::CreateStopReasonToTrace(thread);
- }
- // It looks like exc_sub_code has the 4 bytes of the instruction that
- // triggered the exception, i.e. our breakpoint opcode
- is_actual_breakpoint = exc_code == 1;
- break;
+ } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
+ // is currently returning this so accept it
+ // as indicating a breakpoint until the
+ // kernel is fixed
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
}
+ break;
- default:
- break;
+ case llvm::Triple::aarch64_32:
+ case llvm::Triple::aarch64: {
+ if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
+ {
+ // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
+ // is set
+ is_actual_breakpoint = false;
+ is_trace_if_actual_breakpoint_missing = true;
}
-
- if (is_actual_breakpoint) {
- RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
- addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
-
- ProcessSP process_sp(thread.CalculateProcess());
-
- lldb::BreakpointSiteSP bp_site_sp;
- if (process_sp)
- bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
- if (bp_site_sp && bp_site_sp->IsEnabled()) {
- // Update the PC if we were asked to do so, but only do so if we find
- // a breakpoint that we know about cause this could be a trap
- // instruction in the code
- if (pc_decrement > 0 && adjust_pc_if_needed)
- reg_ctx_sp->SetPC(pc);
-
- // If the breakpoint is for this thread, then we'll report the hit,
- // but if it is for another thread, we can just report no reason. We
- // don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that
- // there's a breakpoint under the pc. If we have an operating system
- // plug-in, we might have set a thread specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about
- // the thread ID so we must always report the breakpoint regardless
- // of the thread.
- if (bp_site_sp->ValidForThisThread(&thread) ||
- thread.GetProcess()->GetOperatingSystem() != nullptr)
- return StopInfo::CreateStopReasonWithBreakpointSiteID(
- thread, bp_site_sp->GetID());
- else if (is_trace_if_actual_breakpoint_missing)
- return StopInfo::CreateStopReasonToTrace(thread);
- else
- return StopInfoSP();
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled data break address from our watchpoint list.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data. Set the hardware index if
+ // that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
}
-
- // Don't call this a trace if we weren't single stepping this thread.
- if (is_trace_if_actual_breakpoint_missing &&
- thread.GetTemporaryResumeState() == eStateStepping) {
+ // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
+ // EXC_BAD_ACCESS
+ if (thread.GetTemporaryResumeState() == eStateStepping)
return StopInfo::CreateStopReasonToTrace(thread);
- }
}
- } break;
+ // It looks like exc_sub_code has the 4 bytes of the instruction that
+ // triggered the exception, i.e. our breakpoint opcode
+ is_actual_breakpoint = exc_code == 1;
+ break;
+ }
- case 7: // EXC_SYSCALL
- case 8: // EXC_MACH_SYSCALL
- case 9: // EXC_RPC_ALERT
- case 10: // EXC_CRASH
+ default:
break;
}
- return StopInfoSP(new StopInfoMachException(
- thread, exc_type, exc_data_count, exc_code, exc_sub_code));
+ if (is_actual_breakpoint) {
+ RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+ addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
+
+ ProcessSP process_sp(thread.CalculateProcess());
+
+ lldb::BreakpointSiteSP bp_site_sp;
+ if (process_sp)
+ bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
+ if (bp_site_sp && bp_site_sp->IsEnabled()) {
+ // Update the PC if we were asked to do so, but only do so if we find
+ // a breakpoint that we know about cause this could be a trap
+ // instruction in the code
+ if (pc_decrement > 0 && adjust_pc_if_needed)
+ reg_ctx_sp->SetPC(pc);
+
+ // If the breakpoint is for this thread, then we'll report the hit,
+ // but if it is for another thread, we can just report no reason. We
+ // don't need to worry about stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices that
+ // there's a breakpoint under the pc. If we have an operating system
+ // plug-in, we might have set a thread specific breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about
+ // the thread ID so we must always report the breakpoint regardless
+ // of the thread.
+ if (bp_site_sp->ValidForThisThread(&thread) ||
+ thread.GetProcess()->GetOperatingSystem() != nullptr)
+ return StopInfo::CreateStopReasonWithBreakpointSiteID(
+ thread, bp_site_sp->GetID());
+ else if (is_trace_if_actual_breakpoint_missing)
+ return StopInfo::CreateStopReasonToTrace(thread);
+ else
+ return StopInfoSP();
+ }
+
+ // Don't call this a trace if we weren't single stepping this thread.
+ if (is_trace_if_actual_breakpoint_missing &&
+ thread.GetTemporaryResumeState() == eStateStepping) {
+ return StopInfo::CreateStopReasonToTrace(thread);
+ }
+ }
+ } break;
+
+ case 7: // EXC_SYSCALL
+ case 8: // EXC_MACH_SYSCALL
+ case 9: // EXC_RPC_ALERT
+ case 10: // EXC_CRASH
+ break;
}
- return StopInfoSP();
+
+ return StopInfoSP(new StopInfoMachException(thread, exc_type, exc_data_count,
+ exc_code, exc_sub_code));
}
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 38209fb24948..74fc90e88547 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -104,8 +104,8 @@ bool UnwindLLDB::AddFirstFrame() {
unwind_done:
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
if (log) {
- log->Printf("th%d Unwind of this thread is complete.",
- m_thread.GetIndexID());
+ LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
}
m_unwind_complete = true;
return false;
@@ -140,10 +140,10 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
// is going to blow out the stack space. If we're still unwinding at that
// point, we're probably never going to finish.
if (cur_idx >= max_stack_depth) {
- if (log)
- log->Printf("%*sFrame %d unwound too many frames, assuming unwind has "
- "gone astray, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log,
+ "%*sFrame %d unwound too many frames, assuming unwind has "
+ "gone astray, stopping.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
}
@@ -161,9 +161,8 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d did not get a RegisterContext, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
}
@@ -181,10 +180,10 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d invalid RegisterContext for this frame, "
- "stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log,
+ "%*sFrame %d invalid RegisterContext for this frame, "
+ "stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
}
if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
@@ -201,10 +200,9 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf(
- "%*sFrame %d did not get CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log,
+ "%*sFrame %d did not get CFA for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
}
if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
@@ -230,17 +228,17 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d did not get a valid CFA for this frame, "
- "stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log,
+ "%*sFrame %d did not get a valid CFA for this frame, "
+ "stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
} else {
- if (log)
- log->Printf("%*sFrame %d had a bad CFA value but we switched the "
- "UnwindPlan being used and got one that looks more "
- "realistic.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log,
+ "%*sFrame %d had a bad CFA value but we switched the "
+ "UnwindPlan being used and got one that looks more "
+ "realistic.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
}
}
@@ -258,10 +256,9 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf(
- "%*sFrame %d did not get PC for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log,
+ "%*sFrame %d did not get PC for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
}
if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) {
@@ -278,18 +275,17 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
}
// Infinite loop where the current cursor is the same as the previous one...
if (prev_frame->start_pc == cursor_sp->start_pc &&
prev_frame->cfa == cursor_sp->cfa) {
- if (log)
- log->Printf("th%d pc of this frame is the same as the previous frame and "
- "CFAs for both frames are identical -- stopping unwind",
- m_thread.GetIndexID());
+ LLDB_LOGF(log,
+ "th%d pc of this frame is the same as the previous frame and "
+ "CFAs for both frames are identical -- stopping unwind",
+ m_thread.GetIndexID());
return nullptr;
}
@@ -337,9 +333,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
new_frame = GetOneMoreFrame(abi);
if (new_frame == nullptr) {
- if (log)
- log->Printf("th%d Unwind of this thread is complete.",
- m_thread.GetIndexID());
+ LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
m_unwind_complete = true;
return false;
}
@@ -395,7 +390,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
return true;
}
-bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
+bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc,
+ bool &behaves_like_zeroth_frame) {
if (m_frames.size() == 0) {
if (!AddFirstFrame())
return false;
@@ -410,6 +406,24 @@ bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
if (idx < m_frames.size()) {
cfa = m_frames[idx]->cfa;
pc = m_frames[idx]->start_pc;
+ if (idx == 0) {
+ // Frame zero always behaves like it.
+ behaves_like_zeroth_frame = true;
+ } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
+ // This could be an asynchronous signal, thus the
+ // pc might point to the interrupted instruction rather
+ // than a post-call instruction
+ behaves_like_zeroth_frame = true;
+ } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
+ // This frame may result from signal processing installing
+ // a pointer to the first byte of a signal-return trampoline
+ // in the return address slot of the frame below, so this
+ // too behaves like the zeroth frame (i.e. the pc might not
+ // be pointing just past a call in it)
+ behaves_like_zeroth_frame = true;
+ } else {
+ behaves_like_zeroth_frame = false;
+ }
return true;
}
return false;
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h
index c512929c185b..ff5db39730b5 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -73,7 +73,8 @@ protected:
uint32_t DoGetFrameCount() override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &start_pc) override;
+ lldb::addr_t &start_pc,
+ bool &behaves_like_zeroth_frame) override;
lldb::RegisterContextSP
DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index 7dc5a5f5fdd1..558edeec1a37 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -43,9 +43,8 @@ uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() {
return m_cursors.size();
}
-bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
- addr_t &cfa,
- addr_t &pc) {
+bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(
+ uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) {
const uint32_t frame_count = GetFrameCount();
if (idx < frame_count) {
if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
@@ -55,6 +54,7 @@ bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
pc = m_cursors[idx].pc;
cfa = m_cursors[idx].fp;
+ behaves_like_zeroth_frame = (idx == 0);
return true;
}
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
index 2208bcc2f2e4..f0bde90a53be 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
@@ -26,7 +26,8 @@ protected:
uint32_t DoGetFrameCount() override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) override;
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) override;
lldb::RegisterContextSP
DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 980169e16c51..ab23589ae9a9 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -33,6 +33,7 @@
#include "ThreadElfCore.h"
using namespace lldb_private;
+namespace ELF = llvm::ELF;
ConstString ProcessElfCore::GetPluginNameStatic() {
static ConstString g_name("elf-core");
@@ -117,16 +118,20 @@ lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
FileRange file_range(header.p_offset, header.p_filesz);
VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range);
- VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
- if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
- last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
- last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
- last_entry->SetRangeEnd(range_entry.GetRangeEnd());
- last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
- } else {
- m_core_aranges.Append(range_entry);
+ // Only add to m_core_aranges if the file size is non zero. Some core files
+ // have PT_LOAD segments for all address ranges, but set f_filesz to zero for
+ // the .text sections since they can be retrieved from the object files.
+ if (header.p_filesz > 0) {
+ VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
+ if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
+ last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
+ last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
+ last_entry->SetRangeEnd(range_entry.GetRangeEnd());
+ last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
+ } else {
+ m_core_aranges.Append(range_entry);
+ }
}
-
// Keep a separate map of permissions that that isn't coalesced so all ranges
// are maintained.
const uint32_t permissions =
@@ -417,7 +422,7 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log) {
if (pr_version > 1)
- log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
+ LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version);
}
// Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
@@ -521,8 +526,8 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
if (note.info.n_name != "FreeBSD")
continue;
- if ((note.info.n_type == FREEBSD::NT_PRSTATUS && have_prstatus) ||
- (note.info.n_type == FREEBSD::NT_PRPSINFO && have_prpsinfo)) {
+ if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
assert(thread_data.gpregset.GetByteSize() > 0);
// Add the new thread to thread list
m_thread_data.push_back(thread_data);
@@ -532,19 +537,19 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
}
switch (note.info.n_type) {
- case FREEBSD::NT_PRSTATUS:
+ case ELF::NT_PRSTATUS:
have_prstatus = true;
ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
break;
- case FREEBSD::NT_PRPSINFO:
+ case ELF::NT_PRPSINFO:
have_prpsinfo = true;
break;
- case FREEBSD::NT_THRMISC: {
+ case ELF::NT_FREEBSD_THRMISC: {
lldb::offset_t offset = 0;
thread_data.name = note.data.GetCStr(&offset, 20);
break;
}
- case FREEBSD::NT_PROCSTAT_AUXV:
+ case ELF::NT_FREEBSD_PROCSTAT_AUXV:
// FIXME: FreeBSD sticks an int at the beginning of the note
m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4);
break;
@@ -771,8 +776,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
if (note.info.n_name != "CORE" && note.info.n_name != "LINUX")
continue;
- if ((note.info.n_type == LINUX::NT_PRSTATUS && have_prstatus) ||
- (note.info.n_type == LINUX::NT_PRPSINFO && have_prpsinfo)) {
+ if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
assert(thread_data.gpregset.GetByteSize() > 0);
// Add the new thread to thread list
m_thread_data.push_back(thread_data);
@@ -782,7 +787,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
}
switch (note.info.n_type) {
- case LINUX::NT_PRSTATUS: {
+ case ELF::NT_PRSTATUS: {
have_prstatus = true;
ELFLinuxPrStatus prstatus;
Status status = prstatus.Parse(note.data, arch);
@@ -795,7 +800,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
thread_data.gpregset = DataExtractor(note.data, header_size, len);
break;
}
- case LINUX::NT_PRPSINFO: {
+ case ELF::NT_PRPSINFO: {
have_prpsinfo = true;
ELFLinuxPrPsInfo prpsinfo;
Status status = prpsinfo.Parse(note.data, arch);
@@ -805,7 +810,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
SetID(prpsinfo.pr_pid);
break;
}
- case LINUX::NT_SIGINFO: {
+ case ELF::NT_SIGINFO: {
ELFLinuxSigInfo siginfo;
Status status = siginfo.Parse(note.data, arch);
if (status.Fail())
@@ -813,7 +818,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
thread_data.signo = siginfo.si_signo;
break;
}
- case LINUX::NT_FILE: {
+ case ELF::NT_FILE: {
m_nt_file_entries.clear();
lldb::offset_t offset = 0;
const uint64_t count = note.data.GetAddress(&offset);
@@ -832,7 +837,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
}
break;
}
- case LINUX::NT_AUXV:
+ case ELF::NT_AUXV:
m_auxv = note.data;
break;
default:
diff --git a/source/Plugins/Process/elf-core/RegisterUtilities.h b/source/Plugins/Process/elf-core/RegisterUtilities.h
index d3b3373150f8..49ad425db445 100644
--- a/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -11,21 +11,11 @@
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "lldb/Utility/DataExtractor.h"
+#include "llvm/BinaryFormat/ELF.h"
namespace lldb_private {
/// Core files PT_NOTE segment descriptor types
-namespace FREEBSD {
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16,
- NT_PPC_VMX = 0x100
-};
-}
-
namespace NETBSD {
enum { NT_PROCINFO = 1, NT_AUXV = 2 };
@@ -76,22 +66,6 @@ enum {
};
}
-namespace LINUX {
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_TASKSTRUCT,
- NT_PLATFORM,
- NT_AUXV,
- NT_FILE = 0x46494c45,
- NT_SIGINFO = 0x53494749,
- NT_PPC_VMX = 0x100,
- NT_PPC_VSX = 0x102,
- NT_PRXFPREG = 0x46e62b7f,
-};
-}
-
struct CoreNote {
ELFNote info;
DataExtractor data;
@@ -122,24 +96,24 @@ DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes,
llvm::ArrayRef<RegsetDesc> RegsetDescs);
constexpr RegsetDesc FPR_Desc[] = {
- {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_FPREGSET},
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
// In a i386 core file NT_FPREGSET is present, but it's not the result
// of the FXSAVE instruction like in 64 bit files.
// The result from FXSAVE is in NT_PRXFPREG for i386 core files
- {llvm::Triple::Linux, llvm::Triple::x86, LINUX::NT_PRXFPREG},
- {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_FPREGSET},
+ {llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
{llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS},
{llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS},
{llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
};
constexpr RegsetDesc PPC_VMX_Desc[] = {
- {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_PPC_VMX},
- {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VMX},
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
};
constexpr RegsetDesc PPC_VSX_Desc[] = {
- {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VSX},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VSX},
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index a5d1fc4a7bff..508c8a3108a6 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -181,9 +181,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
}
if (!reg_interface) {
- if (log)
- log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
- __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
+ LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported",
+ __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
assert(false && "Architecture or OS not supported");
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index fe7ef6b3acea..064bbde8442e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -63,18 +63,16 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
case PacketResult::Success:
break;
default:
- if (log)
- log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteClientBase::%s () ReadPacket(...) => false",
+ __FUNCTION__);
return eStateInvalid;
}
if (response.Empty())
return eStateInvalid;
const char stop_type = response.GetChar();
- if (log)
- log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
- response.GetStringRef().c_str());
+ LLDB_LOGF(log, "GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
+ response.GetStringRef().data());
switch (stop_type) {
case 'W':
@@ -84,9 +82,8 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
// ERROR
return eStateInvalid;
default:
- if (log)
- log->Printf("GDBRemoteClientBase::%s () unrecognized async packet",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteClientBase::%s () unrecognized async packet",
+ __FUNCTION__);
return eStateInvalid;
case 'O': {
std::string inferior_stdout;
@@ -162,10 +159,10 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse(
if (!lock) {
if (Log *log =
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
- log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
- "packet '%.*s' (send_async=%d)",
- __FUNCTION__, int(payload.size()), payload.data(),
- send_async);
+ LLDB_LOGF(log,
+ "GDBRemoteClientBase::%s failed to get mutex, not sending "
+ "packet '%.*s' (send_async=%d)",
+ __FUNCTION__, int(payload.size()), payload.data(), send_async);
return PacketResult::ErrorSendFailed;
}
@@ -181,10 +178,10 @@ GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
if (!lock) {
if (Log *log =
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
- log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
- "packet '%.*s' (send_async=%d)",
- __FUNCTION__, int(payload.size()), payload.data(),
- send_async);
+ LLDB_LOGF(log,
+ "GDBRemoteClientBase::%s failed to get mutex, not sending "
+ "packet '%.*s' (send_async=%d)",
+ __FUNCTION__, int(payload.size()), payload.data(), send_async);
return PacketResult::ErrorSendFailed;
}
@@ -214,13 +211,13 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
return packet_result;
// Response says it wasn't valid
Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
- if (log)
- log->Printf(
- "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
- int(payload.size()), payload.data(), response.GetStringRef().c_str(),
- (i == (max_response_retries - 1))
- ? "using invalid response and giving up"
- : "ignoring response and waiting for another");
+ LLDB_LOGF(
+ log,
+ "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
+ int(payload.size()), payload.data(), response.GetStringRef().data(),
+ (i == (max_response_retries - 1))
+ ? "using invalid response and giving up"
+ : "ignoring response and waiting for another");
}
return packet_result;
}
@@ -228,16 +225,14 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
StringExtractorGDBRemote &response) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
// we want to lock down packet sending while we continue
Lock lock(*this, true);
- if (log)
- log->Printf(
- "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
- __FUNCTION__, int(payload.size()), payload.data());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
+ __FUNCTION__, int(payload.size()), payload.data());
if (SendPacketNoLock(payload) != PacketResult::Success)
return false;
@@ -315,18 +310,16 @@ void GDBRemoteClientBase::ContinueLock::unlock() {
GDBRemoteClientBase::ContinueLock::LockResult
GDBRemoteClientBase::ContinueLock::lock() {
Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
- if (log)
- log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
- __FUNCTION__, m_comm.m_continue_packet.c_str());
+ LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
+ __FUNCTION__, m_comm.m_continue_packet.c_str());
lldbassert(!m_acquired);
std::unique_lock<std::mutex> lock(m_comm.m_mutex);
m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
if (m_comm.m_should_stop) {
m_comm.m_should_stop = false;
- if (log)
- log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() cancelled",
+ __FUNCTION__);
return LockResult::Cancelled;
}
if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
@@ -368,9 +361,8 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, nullptr);
if (bytes_written == 0) {
--m_comm.m_async_count;
- if (log)
- log->Printf("GDBRemoteClientBase::Lock::Lock failed to send "
- "interrupt packet");
+ LLDB_LOGF(log, "GDBRemoteClientBase::Lock::Lock failed to send "
+ "interrupt packet");
return;
}
if (log)
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index 54f69e8caac6..ea294ffcef26 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -24,12 +24,10 @@ public:
virtual void HandleAsyncMisc(llvm::StringRef data) = 0;
virtual void HandleStopReply() = 0;
- // =========================================================================
/// Process asynchronously-received structured data.
///
/// \param[in] data
/// The complete data packet, expected to start with JSON-async.
- // =========================================================================
virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0;
};
@@ -83,42 +81,48 @@ protected:
virtual void OnRunPacketSent(bool first);
private:
- // Variables handling synchronization between the Continue thread and any
- // other threads
- // wishing to send packets over the connection. Either the continue thread has
- // control over
- // the connection (m_is_running == true) or the connection is free for an
- // arbitrary number of
- // other senders to take which indicate their interest by incrementing
- // m_async_count.
- // Semantics of individual states:
- // - m_continue_packet == false, m_async_count == 0: connection is free
- // - m_continue_packet == true, m_async_count == 0: only continue thread is
- // present
- // - m_continue_packet == true, m_async_count > 0: continue thread has
- // control, async threads
- // should interrupt it and wait for it to set m_continue_packet to false
- // - m_continue_packet == false, m_async_count > 0: async threads have
- // control, continue
- // thread needs to wait for them to finish (m_async_count goes down to 0).
+ /// Variables handling synchronization between the Continue thread and any
+ /// other threads wishing to send packets over the connection. Either the
+ /// continue thread has control over the connection (m_is_running == true) or
+ /// the connection is free for an arbitrary number of other senders to take
+ /// which indicate their interest by incrementing m_async_count.
+ ///
+ /// Semantics of individual states:
+ ///
+ /// - m_continue_packet == false, m_async_count == 0:
+ /// connection is free
+ /// - m_continue_packet == true, m_async_count == 0:
+ /// only continue thread is present
+ /// - m_continue_packet == true, m_async_count > 0:
+ /// continue thread has control, async threads should interrupt it and wait
+ /// for it to set m_continue_packet to false
+ /// - m_continue_packet == false, m_async_count > 0:
+ /// async threads have control, continue thread needs to wait for them to
+ /// finish (m_async_count goes down to 0).
+ /// @{
std::mutex m_mutex;
std::condition_variable m_cv;
- // Packet with which to resume after an async interrupt. Can be changed by an
- // async thread
- // e.g. to inject a signal.
+
+ /// Packet with which to resume after an async interrupt. Can be changed by
+ /// an async thread e.g. to inject a signal.
std::string m_continue_packet;
- // When was the interrupt packet sent. Used to make sure we time out if the
- // stub does not
- // respond to interrupt requests.
+
+ /// When was the interrupt packet sent. Used to make sure we time out if the
+ /// stub does not respond to interrupt requests.
std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
+
+ /// Number of threads interested in sending.
uint32_t m_async_count;
+
+ /// Whether the continue thread has control.
bool m_is_running;
- bool m_should_stop; // Whether we should resume after a stop.
- // end of continue thread synchronization block
- // This handles the synchronization between individual async threads. For now
- // they just use a
- // simple mutex.
+ /// Whether we should resume after a stop.
+ bool m_should_stop;
+ /// @}
+
+ /// This handles the synchronization between individual async threads. For
+ /// now they just use a simple mutex.
std::recursive_mutex m_async_mutex;
bool ShouldStop(const UnixSignals &signals,
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 11052eff948f..144ae103faa4 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include "lldb/Core/StreamFile.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -38,6 +39,8 @@
#if defined(__APPLE__)
#define DEBUGSERVER_BASENAME "debugserver"
+#elif defined(_WIN32)
+#define DEBUGSERVER_BASENAME "lldb-server.exe"
#else
#define DEBUGSERVER_BASENAME "lldb-server"
#endif
@@ -99,10 +102,8 @@ size_t GDBRemoteCommunication::SendAck() {
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '+';
const size_t bytes_written = Write(&ch, 1, status, nullptr);
- if (log)
- log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
- bytes_written);
+ LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+ m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written);
return bytes_written;
}
@@ -111,10 +112,8 @@ size_t GDBRemoteCommunication::SendNack() {
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '-';
const size_t bytes_written = Write(&ch, 1, status, nullptr);
- if (log)
- log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
- bytes_written);
+ LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+ m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written);
return bytes_written;
}
@@ -172,13 +171,12 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
strm.Printf("%*s", (int)3, p);
log->PutString(strm.GetString());
} else
- log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
- (int)packet_length, packet_data);
+ LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %.*s",
+ (uint64_t)bytes_written, (int)packet_length, packet_data);
}
m_history.AddPacket(packet.str(), packet_length,
- GDBRemoteCommunicationHistory::ePacketTypeSend,
- bytes_written);
+ GDBRemotePacket::ePacketTypeSend, bytes_written);
if (bytes_written == packet_length) {
if (!skip_ack && GetSendAcks())
@@ -186,9 +184,8 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
else
return PacketResult::Success;
} else {
- if (log)
- log->Printf("error: failed to send packet: %.*s", (int)packet_length,
- packet_data);
+ LLDB_LOGF(log, "error: failed to send packet: %.*s", (int)packet_length,
+ packet_data);
}
}
return PacketResult::ErrorSendFailed;
@@ -332,11 +329,12 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
std::string regex_str = "^";
regex_str += echo_packet;
regex_str += "$";
- response_regex.Compile(regex_str);
+ response_regex = RegularExpression(regex_str);
} else {
echo_packet_len =
::snprintf(echo_packet, sizeof(echo_packet), "qC");
- response_regex.Compile(llvm::StringRef("^QC[0-9A-Fa-f]+$"));
+ response_regex =
+ RegularExpression(llvm::StringRef("^QC[0-9A-Fa-f]+$"));
}
PacketResult echo_packet_result =
@@ -489,11 +487,10 @@ bool GDBRemoteCommunication::DecompressPacket() {
llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1));
bool success = packet_checksum == actual_checksum;
if (!success) {
- if (log)
- log->Printf(
- "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
- (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum,
- (uint8_t)actual_checksum);
+ LLDB_LOGF(log,
+ "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
+ (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum,
+ (uint8_t)actual_checksum);
}
// Send the ack or nack if needed
if (!success) {
@@ -651,8 +648,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
if (src && src_len > 0) {
if (log && log->GetVerbose()) {
StreamString s;
- log->Printf("GDBRemoteCommunication::%s adding %u bytes: %.*s",
- __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s adding %u bytes: %.*s",
+ __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
}
m_bytes.append((const char *)src, src_len);
}
@@ -733,9 +730,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
break;
}
}
- if (log)
- log->Printf("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
- __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
+ __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
m_bytes.erase(0, idx - 1);
} break;
}
@@ -752,7 +748,6 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
size_t content_end = content_start + content_length;
bool success = true;
- std::string &packet_str = packet.GetStringRef();
if (log) {
// If logging was just enabled and we have history, then dump out what
// we have to the log so we get the historical context. The Dump() call
@@ -800,25 +795,23 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
log->PutString(strm.GetString());
} else {
if (CompressionIsEnabled())
- log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s",
- (uint64_t)original_packet_size, (uint64_t)total_length,
- (int)(total_length), m_bytes.c_str());
+ LLDB_LOGF(log, "<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s",
+ (uint64_t)original_packet_size, (uint64_t)total_length,
+ (int)(total_length), m_bytes.c_str());
else
- log->Printf("<%4" PRIu64 "> read packet: %.*s",
- (uint64_t)total_length, (int)(total_length),
- m_bytes.c_str());
+ LLDB_LOGF(log, "<%4" PRIu64 "> read packet: %.*s",
+ (uint64_t)total_length, (int)(total_length),
+ m_bytes.c_str());
}
}
m_history.AddPacket(m_bytes, total_length,
- GDBRemoteCommunicationHistory::ePacketTypeRecv,
- total_length);
+ GDBRemotePacket::ePacketTypeRecv, total_length);
- // Clear packet_str in case there is some existing data in it.
- packet_str.clear();
// Copy the packet from m_bytes to packet_str expanding the run-length
// encoding in the process. Reserve enough byte for the most common case
// (no RLE used)
+ std ::string packet_str;
packet_str.reserve(m_bytes.length());
for (std::string::const_iterator c = m_bytes.begin() + content_start;
c != m_bytes.begin() + content_end; ++c) {
@@ -841,6 +834,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
packet_str.push_back(*c);
}
}
+ packet = StringExtractorGDBRemote(packet_str);
if (m_bytes[0] == '$' || m_bytes[0] == '%') {
assert(checksum_idx < m_bytes.size());
@@ -853,11 +847,11 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
llvm::StringRef(m_bytes).slice(content_start, content_end));
success = packet_checksum == actual_checksum;
if (!success) {
- if (log)
- log->Printf("error: checksum mismatch: %.*s expected 0x%2.2x, "
- "got 0x%2.2x",
- (int)(total_length), m_bytes.c_str(),
- (uint8_t)packet_checksum, (uint8_t)actual_checksum);
+ LLDB_LOGF(log,
+ "error: checksum mismatch: %.*s expected 0x%2.2x, "
+ "got 0x%2.2x",
+ (int)(total_length), m_bytes.c_str(),
+ (uint8_t)packet_checksum, (uint8_t)actual_checksum);
}
// Send the ack or nack if needed
if (!success)
@@ -867,9 +861,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
}
} else {
success = false;
- if (log)
- log->Printf("error: invalid checksum in packet: '%s'\n",
- m_bytes.c_str());
+ LLDB_LOGF(log, "error: invalid checksum in packet: '%s'\n",
+ m_bytes.c_str());
}
}
@@ -933,10 +926,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
const char *url, Platform *platform, ProcessLaunchInfo &launch_info,
uint16_t *port, const Args *inferior_args, int pass_comm_fd) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")",
- __FUNCTION__, url ? url : "<empty>",
- port ? *port : uint16_t(0));
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")",
+ __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));
Status error;
// If we locate debugserver, keep that located version around
@@ -953,10 +944,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (!env_debugserver_path.empty()) {
debugserver_file_spec.SetFile(env_debugserver_path,
FileSpec::Style::native);
- if (log)
- log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
- "from environment variable: %s",
- __FUNCTION__, env_debugserver_path.c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() gdb-remote stub exe path set "
+ "from environment variable: %s",
+ __FUNCTION__, env_debugserver_path.c_str());
} else
debugserver_file_spec = g_debugserver_file_spec;
bool debugserver_exists =
@@ -968,10 +959,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
debugserver_exists = FileSystem::Instance().Exists(debugserver_file_spec);
if (debugserver_exists) {
- if (log)
- log->Printf(
- "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
- __FUNCTION__, debugserver_file_spec.GetPath().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
g_debugserver_file_spec = debugserver_file_spec;
} else {
@@ -985,10 +975,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// exist
debugserver_exists = true;
} else {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() could not find "
- "gdb-remote stub exe '%s'",
- __FUNCTION__, debugserver_file_spec.GetPath().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() could not find "
+ "gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
}
// Don't cache the platform specific GDB server binary as it could
// change from platform to platform
@@ -1052,10 +1042,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe",
false, named_pipe_path);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "named pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "named pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
debugserver_args.AppendArgument(llvm::StringRef("--named-pipe"));
@@ -1065,10 +1055,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// using using an unnamed pipe...
error = socket_pipe.CreateNew(true);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "unnamed pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "unnamed pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
pipe_t write = socket_pipe.GetWritePipe();
@@ -1081,10 +1071,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// debugserver connect to us..
error = StartListenThread("127.0.0.1", 0);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() unable to start listen "
- "thread: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() unable to start listen "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -1104,9 +1094,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
*port = port_;
} else {
error.SetErrorString("failed to bind to port 0 on 127.0.0.1");
- if (log)
- log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s() failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
}
@@ -1148,10 +1137,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (has_env_var) {
debugserver_args.AppendArgument(llvm::StringRef(extra_arg));
- if (log)
- log->Printf("GDBRemoteCommunication::%s adding env var %s contents "
- "to stub command line (%s)",
- __FUNCTION__, env_var_name, extra_arg.c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s adding env var %s contents "
+ "to stub command line (%s)",
+ __FUNCTION__, env_var_name, extra_arg.c_str());
}
} while (has_env_var);
@@ -1177,8 +1166,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
StreamString string_stream;
Platform *const platform = nullptr;
launch_info.Dump(string_stream, platform);
- log->Printf("launch info for gdb-remote stub:\n%s",
- string_stream.GetData());
+ LLDB_LOGF(log, "launch info for gdb-remote stub:\n%s",
+ string_stream.GetData());
}
error = Host::LaunchProcess(launch_info);
@@ -1188,11 +1177,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (named_pipe_path.size() > 0) {
error = socket_pipe.OpenAsReader(named_pipe_path, false);
if (error.Fail())
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to open named pipe %s for reading: %s",
- __FUNCTION__, named_pipe_path.c_str(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "failed to open named pipe %s for reading: %s",
+ __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
if (socket_pipe.CanWrite())
@@ -1209,24 +1197,22 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
uint16_t child_port = StringConvert::ToUInt32(port_cstr, 0);
if (*port == 0 || *port == child_port) {
*port = child_port;
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "debugserver listens %u port",
- __FUNCTION__, *port);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "debugserver listens %u port",
+ __FUNCTION__, *port);
} else {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "debugserver listening on port "
- "%d but requested port was %d",
- __FUNCTION__, (uint32_t)child_port,
- (uint32_t)(*port));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "debugserver listening on port "
+ "%d but requested port was %d",
+ __FUNCTION__, (uint32_t)child_port, (uint32_t)(*port));
}
} else {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to read a port value from pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "failed to read a port value from pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
socket_pipe.Close();
}
@@ -1234,10 +1220,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (named_pipe_path.size() > 0) {
const auto err = socket_pipe.Delete(named_pipe_path);
if (err.Fail()) {
- if (log)
- log->Printf(
- "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
}
}
@@ -1249,9 +1234,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
}
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
}
return error;
@@ -1351,7 +1335,7 @@ void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
if (type == PacketType::Notify) {
// put this packet into an event
- const char *pdata = packet.GetStringRef().c_str();
+ const char *pdata = packet.GetStringRef().data();
// as the communication class, we are a broadcaster and the async thread
// is tuned to listen to us
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 9797184026e0..feb9f0589cee 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -23,7 +23,6 @@
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
@@ -35,17 +34,15 @@
#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/JSON.h"
-#if defined(__APPLE__)
-#ifndef HAVE_LIBCOMPRESSION
-#define HAVE_LIBCOMPRESSION
-#endif
+#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif
using namespace lldb;
-using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private;
using namespace std::chrono;
// GDBRemoteCommunicationClient constructor
@@ -342,7 +339,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
// not, we assume no limit
// build the qSupported packet
- std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
+ std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
StreamString packet;
packet.PutCString("qSupported");
for (uint32_t i = 0; i < features.size(); ++i) {
@@ -354,7 +351,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
if (SendPacketAndWaitForResponse(packet.GetString(), response,
/*send_async=*/false) ==
PacketResult::Success) {
- const char *response_cstr = response.GetStringRef().c_str();
+ const char *response_cstr = response.GetStringRef().data();
// Hang on to the qSupported packet, so that platforms can do custom
// configuration of the transport before attaching/launching the process.
@@ -439,8 +436,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_max_packet_size = UINT64_MAX; // Must have been a garbled response
Log *log(
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("Garbled PacketSize spec in qSupported response");
+ LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
}
}
}
@@ -469,7 +465,7 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
m_supports_vCont_S = eLazyBoolNo;
if (SendPacketAndWaitForResponse("vCont?", response, false) ==
PacketResult::Success) {
- const char *response_cstr = response.GetStringRef().c_str();
+ const char *response_cstr = response.GetStringRef().data();
if (::strstr(response_cstr, ";c"))
m_supports_vCont_c = eLazyBoolYes;
@@ -525,9 +521,10 @@ GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
if (!lock) {
if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
- log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
- "for %s packet.",
- __FUNCTION__, payload.GetData());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
+ "for %s packet.",
+ __FUNCTION__, payload.GetData());
return PacketResult::ErrorNoSequenceLock;
}
@@ -660,10 +657,10 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
if (!lock) {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "packets with prefix '%s'",
- payload_prefix);
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "packets with prefix '%s'",
+ payload_prefix);
return PacketResult::ErrorNoSequenceLock;
}
@@ -934,6 +931,11 @@ llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
return m_os_version;
}
+llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
+ GetHostInfo();
+ return m_maccatalyst_version;
+}
+
bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
if (GetHostInfo()) {
if (!m_os_build.empty()) {
@@ -1136,6 +1138,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
uint32_t sub = 0;
std::string arch_name;
std::string os_name;
+ std::string environment;
std::string vendor_name;
std::string triple;
std::string distribution_id;
@@ -1175,7 +1178,11 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
extractor.GetHexByteString(m_os_kernel);
++num_keys_decoded;
} else if (name.equals("ostype")) {
- os_name = value;
+ if (value.equals("maccatalyst")) {
+ os_name = "ios";
+ environment = "macabi";
+ } else
+ os_name = value;
++num_keys_decoded;
} else if (name.equals("vendor")) {
vendor_name = value;
@@ -1199,6 +1206,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
{
if (!m_os_version.tryParse(value))
++num_keys_decoded;
+ } else if (name.equals("maccatalyst_version")) {
+ if (!m_maccatalyst_version.tryParse(value))
+ ++num_keys_decoded;
} else if (name.equals("watchpoint_exceptions_received")) {
m_watchpoints_trigger_after_instruction =
llvm::StringSwitch<LazyBool>(value)
@@ -1236,6 +1246,8 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
llvm::StringRef(vendor_name));
if (!os_name.empty())
m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ if (!environment.empty())
+ m_host_arch.GetTriple().setEnvironmentName(environment);
}
} else {
std::string triple;
@@ -1259,6 +1271,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
host_triple.getOS() == llvm::Triple::Darwin) {
switch (m_host_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::arm:
case llvm::Triple::thumb:
host_triple.setOS(llvm::Triple::IOS);
@@ -1284,14 +1297,15 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
assert(byte_order == m_host_arch.GetByteOrder());
}
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s parsed host "
- "architecture as %s, triple as %s from triple text %s",
- __FUNCTION__, m_host_arch.GetArchitectureName()
- ? m_host_arch.GetArchitectureName()
- : "<null-arch-name>",
- m_host_arch.GetTriple().getTriple().c_str(),
- triple.c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s parsed host "
+ "architecture as %s, triple as %s from triple text %s",
+ __FUNCTION__,
+ m_host_arch.GetArchitectureName()
+ ? m_host_arch.GetArchitectureName()
+ : "<null-arch-name>",
+ m_host_arch.GetTriple().getTriple().c_str(),
+ triple.c_str());
}
if (!distribution_id.empty())
m_host_arch.SetDistributionId(distribution_id.c_str());
@@ -1893,7 +1907,7 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
} else if (name.equals("euid")) {
uint32_t uid = UINT32_MAX;
value.getAsInteger(0, uid);
- process_info.SetEffectiveGroupID(uid);
+ process_info.SetEffectiveUserID(uid);
} else if (name.equals("gid")) {
uint32_t gid = UINT32_MAX;
value.getAsInteger(0, gid);
@@ -1914,6 +1928,26 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
std::string name;
extractor.GetHexByteString(name);
process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
+ } else if (name.equals("args")) {
+ llvm::StringRef encoded_args(value), hex_arg;
+
+ bool is_arg0 = true;
+ while (!encoded_args.empty()) {
+ std::tie(hex_arg, encoded_args) = encoded_args.split('-');
+ std::string arg;
+ StringExtractor extractor(hex_arg);
+ if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
+ // In case of wrong encoding, we discard all the arguments
+ process_info.GetArguments().Clear();
+ process_info.SetArg0("");
+ break;
+ }
+ if (is_arg0)
+ process_info.SetArg0(arg);
+ else
+ process_info.GetArguments().AppendArgument(arg);
+ is_arg0 = false;
+ }
} else if (name.equals("cputype")) {
value.getAsInteger(0, cpu);
} else if (name.equals("cpusubtype")) {
@@ -1987,6 +2021,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
uint32_t sub = 0;
std::string arch_name;
std::string os_name;
+ std::string environment;
std::string vendor_name;
std::string triple;
std::string elf_abi;
@@ -2007,7 +2042,11 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
extractor.GetHexByteString(triple);
++num_keys_decoded;
} else if (name.equals("ostype")) {
- os_name = value;
+ if (value.equals("maccatalyst")) {
+ os_name = "ios";
+ environment = "macabi";
+ } else
+ os_name = value;
++num_keys_decoded;
} else if (name.equals("vendor")) {
vendor_name = value;
@@ -2048,6 +2087,8 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
} else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
!vendor_name.empty()) {
llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
+ if (!environment.empty())
+ triple.setEnvironmentName(environment);
assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
assert(triple.getObjectFormat() != llvm::Triple::Wasm);
@@ -2064,12 +2105,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
break;
case llvm::Triple::Wasm:
case llvm::Triple::XCOFF:
- if (log)
- log->Printf("error: not supported target architecture");
+ LLDB_LOGF(log, "error: not supported target architecture");
return false;
case llvm::Triple::UnknownObjectFormat:
- if (log)
- log->Printf("error: failed to determine target architecture");
+ LLDB_LOGF(log, "error: failed to determine target architecture");
return false;
}
@@ -2081,8 +2120,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
}
m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
}
return true;
}
@@ -2156,8 +2197,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
packet.Printf("egid:%u;",
match_info.GetProcessInfo().GetEffectiveGroupID());
- if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
- packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
+ packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
const ArchSpec &match_arch =
match_info.GetProcessInfo().GetArchitecture();
@@ -2178,8 +2218,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
if (!DecodeProcessInfoResponse(response, process_info))
break;
process_infos.Append(process_info);
- response.GetStringRef().clear();
- response.SetFilePos(0);
+ response = StringExtractorGDBRemote();
} while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
PacketResult::Success);
} else {
@@ -2641,9 +2680,8 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo(
uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
- __FUNCTION__, insert ? "add" : "remove", addr);
+ LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
+ __FUNCTION__, insert ? "add" : "remove", addr);
// Check if the stub is known not to support this breakpoint type
if (!SupportsGDBStoppointPacket(type))
@@ -2745,9 +2783,8 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
#if !defined(LLDB_CONFIGURATION_DEBUG)
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "packet 'qfThreadInfo'");
+ LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending "
+ "packet 'qfThreadInfo'");
#endif
sequence_mutex_unavailable = true;
}
@@ -2879,7 +2916,7 @@ static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
}
lldb::user_id_t
GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
- uint32_t flags, mode_t mode,
+ File::OpenOptions flags, mode_t mode,
Status &error) {
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
@@ -3146,7 +3183,8 @@ bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
if (arch.IsValid() &&
arch.GetTriple().getVendor() == llvm::Triple::Apple &&
arch.GetTriple().getOS() == llvm::Triple::IOS &&
- arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
+ arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
m_avoid_g_packets = eLazyBoolYes;
uint32_t gdb_server_version = GetGDBServerProgramVersion();
if (gdb_server_version != 0) {
@@ -3592,21 +3630,21 @@ ParseModuleSpec(StructuredData::Dictionary *dict) {
llvm::Optional<std::vector<ModuleSpec>>
GDBRemoteCommunicationClient::GetModulesInfo(
llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
+ namespace json = llvm::json;
+
if (!m_supports_jModulesInfo)
return llvm::None;
- JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
+ json::Array module_array;
for (const FileSpec &module_file_spec : module_file_specs) {
- JSONObject::SP module_sp = std::make_shared<JSONObject>();
- module_array_sp->AppendObject(module_sp);
- module_sp->SetObject(
- "file", std::make_shared<JSONString>(module_file_spec.GetPath(false)));
- module_sp->SetObject("triple",
- std::make_shared<JSONString>(triple.getTriple()));
+ module_array.push_back(
+ json::Object{{"file", module_file_spec.GetPath(false)},
+ {"triple", triple.getTriple()}});
}
StreamString unescaped_payload;
unescaped_payload.PutCString("jModulesInfo:");
- module_array_sp->Write(unescaped_payload);
+ unescaped_payload.AsRawOstream() << std::move(module_array);
+
StreamGDBRemote payload;
payload.PutEscapedBytes(unescaped_payload.GetString().data(),
unescaped_payload.GetSize());
@@ -3796,8 +3834,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
lldb_private::SymbolContextList sc_list;
- if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(
- ConstString(symbol_name), eSymbolTypeAny, sc_list)) {
+ process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ ConstString(symbol_name), eSymbolTypeAny, sc_list);
+ if (!sc_list.IsEmpty()) {
const size_t num_scs = sc_list.GetSize();
for (size_t sc_idx = 0;
sc_idx < num_scs &&
@@ -3873,9 +3912,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
} else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
- log->Printf(
- "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
+ __FUNCTION__);
}
}
}
@@ -3899,26 +3938,27 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
!m_supported_async_json_packets_sp->GetAsArray()) {
// We were returned something other than a JSON array. This is
// invalid. Clear it out.
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s(): "
- "QSupportedAsyncJSONPackets returned invalid "
- "result: %s",
- __FUNCTION__, response.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets returned invalid "
+ "result: %s",
+ __FUNCTION__, response.GetStringRef().data());
m_supported_async_json_packets_sp.reset();
}
} else {
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s(): "
- "QSupportedAsyncJSONPackets unsupported",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets unsupported",
+ __FUNCTION__);
}
if (log && m_supported_async_json_packets_sp) {
StreamString stream;
m_supported_async_json_packets_sp->Dump(stream);
- log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
- "JSON packets: %s",
- __FUNCTION__, stream.GetData());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s(): supported async "
+ "JSON packets: %s",
+ __FUNCTION__, stream.GetData());
}
}
@@ -3980,14 +4020,14 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
if (result == PacketResult::Success) {
// We failed if the config result comes back other than OK.
- if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
+ if (strcmp(response.GetStringRef().data(), "OK") == 0) {
// Okay!
error.Clear();
} else {
error.SetErrorStringWithFormat("configuring StructuredData feature "
"%s failed with error %s",
type_name.AsCString(),
- response.GetStringRef().c_str());
+ response.GetStringRef().data());
}
} else {
// Can we get more data here on the failure?
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index de85c9f8b67b..574cd0fd70c5 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -17,8 +17,9 @@
#include <string>
#include <vector>
+#include "lldb/Host/File.h"
#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/StreamGDBRemote.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/StructuredData.h"
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
@@ -248,6 +249,8 @@ public:
llvm::VersionTuple GetOSVersion();
+ llvm::VersionTuple GetMacCatalystVersion();
+
bool GetOSBuildString(std::string &s);
bool GetOSKernelDescription(std::string &s);
@@ -348,7 +351,7 @@ public:
size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable);
- lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
mode_t mode, Status &error);
bool CloseFile(lldb::user_id_t fd, Status &error);
@@ -548,6 +551,7 @@ protected:
ArchSpec m_host_arch;
ArchSpec m_process_arch;
llvm::VersionTuple m_os_version;
+ llvm::VersionTuple m_maccatalyst_version;
std::string m_os_build;
std::string m_os_kernel;
std::string m_hostname;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index bcddb4faf863..d2cc32f63f20 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -18,12 +18,6 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const {
- yaml::Output yout(strm);
- yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this);
- strm.flush();
-}
-
GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
: m_packets(), m_curr_idx(0), m_total_packet_count(0),
m_dumped_to_log(false) {
@@ -33,7 +27,8 @@ GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
-void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
+void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
+ GDBRemotePacket::Type type,
uint32_t bytes_transmitted) {
const size_t size = m_packets.size();
if (size == 0)
@@ -50,7 +45,8 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
}
void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
- uint32_t src_len, PacketType type,
+ uint32_t src_len,
+ GDBRemotePacket::Type type,
uint32_t bytes_transmitted) {
const size_t size = m_packets.size();
if (size == 0)
@@ -72,13 +68,12 @@ void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
const uint32_t stop_idx = m_curr_idx + size;
for (uint32_t i = first_idx; i < stop_idx; ++i) {
const uint32_t idx = NormalizeIndex(i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
+ const GDBRemotePacket &entry = m_packets[idx];
+ if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
+ entry.packet.data.empty())
break;
- strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
- entry.packet_idx, entry.tid, entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.data.c_str());
+ strm.Printf("history[%u] ", entry.packet_idx);
+ entry.Dump(strm);
}
}
@@ -92,51 +87,15 @@ void GDBRemoteCommunicationHistory::Dump(Log *log) const {
const uint32_t stop_idx = m_curr_idx + size;
for (uint32_t i = first_idx; i < stop_idx; ++i) {
const uint32_t idx = NormalizeIndex(i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
+ const GDBRemotePacket &entry = m_packets[idx];
+ if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
+ entry.packet.data.empty())
break;
- log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
- entry.packet_idx, entry.tid, entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.data.c_str());
+ LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
+ entry.packet_idx, entry.tid, entry.bytes_transmitted,
+ (entry.type == GDBRemotePacket::ePacketTypeSend) ? "send"
+ : "read",
+ entry.packet.data.c_str());
}
}
-void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>::
- enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) {
- io.enumCase(value, "Invalid",
- GDBRemoteCommunicationHistory::ePacketTypeInvalid);
- io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend);
- io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv);
-}
-
-void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::
- output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *,
- raw_ostream &Out) {
- Out << toHex(Val.data);
-}
-
-StringRef
-yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input(
- StringRef Scalar, void *,
- GDBRemoteCommunicationHistory::Entry::BinaryData &Val) {
- Val.data = fromHex(Scalar);
- return {};
-}
-
-void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping(
- IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
- io.mapRequired("packet", Entry.packet);
- io.mapRequired("type", Entry.type);
- io.mapRequired("bytes", Entry.bytes_transmitted);
- io.mapRequired("index", Entry.packet_idx);
- io.mapRequired("tid", Entry.tid);
-}
-
-StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate(
- IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
- if (Entry.bytes_transmitted != Entry.packet.data.size())
- return "BinaryData size doesn't match bytes transmitted";
-
- return {};
-}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index 85f112b50623..c006fbd34a4b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/lldb-public.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
@@ -25,46 +26,17 @@ class GDBRemoteCommunicationHistory {
public:
friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>;
- enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
-
- /// Entry in the ring buffer containing the packet data, its type, size and
- /// index. Entries can be serialized to file.
- struct Entry {
- Entry()
- : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
- packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
-
- void Clear() {
- packet.data.clear();
- type = ePacketTypeInvalid;
- bytes_transmitted = 0;
- packet_idx = 0;
- tid = LLDB_INVALID_THREAD_ID;
- }
-
- struct BinaryData {
- std::string data;
- };
-
- void Serialize(llvm::raw_ostream &strm) const;
-
- BinaryData packet;
- PacketType type;
- uint32_t bytes_transmitted;
- uint32_t packet_idx;
- lldb::tid_t tid;
- };
-
GDBRemoteCommunicationHistory(uint32_t size = 0);
~GDBRemoteCommunicationHistory();
// For single char packets for ack, nack and /x03
- void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted);
-
- void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
+ void AddPacket(char packet_char, GDBRemotePacket::Type type,
uint32_t bytes_transmitted);
+ void AddPacket(const std::string &src, uint32_t src_len,
+ GDBRemotePacket::Type type, uint32_t bytes_transmitted);
+
void Dump(Stream &strm) const;
void Dump(Log *log) const;
bool DidDumpToLog() const { return m_dumped_to_log; }
@@ -97,7 +69,7 @@ private:
return m_packets.empty() ? 0 : i % m_packets.size();
}
- std::vector<Entry> m_packets;
+ std::vector<GDBRemotePacket> m_packets;
uint32_t m_curr_idx;
uint32_t m_total_packet_count;
mutable bool m_dumped_to_log;
@@ -107,49 +79,4 @@ private:
} // namespace process_gdb_remote
} // namespace lldb_private
-LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry)
-
-namespace llvm {
-namespace yaml {
-
-template <>
-struct ScalarEnumerationTraits<lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::PacketType> {
- static void enumeration(IO &io,
- lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::PacketType &value);
-};
-
-template <>
-struct ScalarTraits<lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::Entry::BinaryData> {
- static void output(const lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::Entry::BinaryData &,
- void *, raw_ostream &);
-
- static StringRef
- input(StringRef, void *,
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry::
- BinaryData &);
-
- static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
-};
-
-template <>
-struct MappingTraits<
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> {
- static void
- mapping(IO &io,
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry
- &Entry);
-
- static StringRef validate(
- IO &io,
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &);
-};
-
-} // namespace yaml
-} // namespace llvm
-
#endif // liblldb_GDBRemoteCommunicationHistory_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
index 417f5737a30f..2d26c550dc76 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -9,6 +9,7 @@
#include <errno.h>
#include "lldb/Host/Config.h"
+#include "llvm/ADT/ScopeExit.h"
#include "GDBRemoteCommunicationReplayServer.h"
#include "ProcessGDBRemoteLog.h"
@@ -127,7 +128,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
while (!m_packet_history.empty()) {
// Pop last packet from the history.
- GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
+ GDBRemotePacket entry = m_packet_history.back();
m_packet_history.pop_back();
// We've handled the handshake implicitly before. Skip the packet and move
@@ -135,7 +136,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
if (entry.packet.data == "+")
continue;
- if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeSend) {
+ if (entry.type == GDBRemotePacket::ePacketTypeSend) {
if (unexpected(entry.packet.data, packet.GetStringRef())) {
LLDB_LOG(log,
"GDBRemoteCommunicationReplayServer expected packet: '{0}'",
@@ -149,14 +150,14 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
// Ignore QEnvironment packets as they're handled earlier.
if (entry.packet.data.find("QEnvironment") == 1) {
assert(m_packet_history.back().type ==
- GDBRemoteCommunicationHistory::ePacketTypeRecv);
+ GDBRemotePacket::ePacketTypeRecv);
m_packet_history.pop_back();
}
continue;
}
- if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeInvalid) {
+ if (entry.type == GDBRemotePacket::ePacketTypeInvalid) {
LLDB_LOG(
log,
"GDBRemoteCommunicationReplayServer skipped invalid packet: '{0}'",
@@ -175,10 +176,6 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
return packet_result;
}
-LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
- std::vector<
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>)
-
llvm::Error
GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) {
auto error_or_file = MemoryBuffer::getFile(path.GetPath());
@@ -256,11 +253,10 @@ void GDBRemoteCommunicationReplayServer::ReceivePacket(
thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) {
GDBRemoteCommunicationReplayServer *server =
(GDBRemoteCommunicationReplayServer *)arg;
-
+ auto D = make_scope_exit([&]() { server->Disconnect(); });
EventSP event_sp;
bool done = false;
-
- while (true) {
+ while (!done) {
if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
index 26d65e265463..0b5e910f7c6a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
@@ -62,7 +62,7 @@ protected:
static lldb::thread_result_t AsyncThread(void *arg);
/// Replay history with the oldest packet at the end.
- std::vector<GDBRemoteCommunicationHistory::Entry> m_packet_history;
+ std::vector<GDBRemotePacket> m_packet_history;
/// Server thread.
Broadcaster m_async_broadcaster;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 49cbeb023fd5..ac6ecffcf854 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -59,14 +59,13 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse(
break;
case StringExtractorGDBRemote::eServerPacketType_unimplemented:
- packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str());
+ packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
break;
default:
auto handler_it = m_packet_handlers.find(packet_type);
if (handler_it == m_packet_handlers.end())
- packet_result =
- SendUnimplementedResponse(packet.GetStringRef().c_str());
+ packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
else
packet_result = handler_it->second(packet, error, interrupt, quit);
break;
@@ -139,10 +138,9 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendIllFormedResponse(
const StringExtractorGDBRemote &failed_packet, const char *message) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
- if (log)
- log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
- __FUNCTION__, failed_packet.GetStringRef().c_str(),
- message ? message : "");
+ LLDB_LOGF(log, "GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
+ __FUNCTION__, failed_packet.GetStringRef().data(),
+ message ? message : "");
return SendErrorResponse(0x03);
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index d095c7a057ad..37980d914dc2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -29,12 +29,13 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Platform.h"
#include "lldb/Utility/Endian.h"
-#include "lldb/Utility/JSON.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Support/JSON.h"
#include "ProcessGDBRemoteLog.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
@@ -43,11 +44,10 @@
#include "lldb/Host/android/HostInfoAndroid.h"
#endif
-#include "llvm/ADT/StringSwitch.h"
using namespace lldb;
-using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private;
#ifdef __ANDROID__
const static uint32_t g_default_packet_timeout_sec = 20; // seconds
@@ -231,6 +231,7 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
#else
if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
+ host_arch.GetMachine() == llvm::Triple::aarch64_32 ||
host_arch.GetMachine() == llvm::Triple::aarch64_be ||
host_arch.GetMachine() == llvm::Triple::arm ||
host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS())
@@ -260,6 +261,15 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
response.PutChar(';');
}
+#if defined(__APPLE__)
+ llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();
+ if (!maccatalyst_version.empty()) {
+ response.Format("maccatalyst_version:{0}",
+ maccatalyst_version.getAsString());
+ response.PutChar(';');
+ }
+#endif
+
std::string s;
if (HostInfo::GetOSBuildString(s)) {
response.PutCString("os_build:");
@@ -421,8 +431,7 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName(
StringExtractorGDBRemote &packet) {
#if !defined(LLDB_DISABLE_POSIX)
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
// Packet format: "qUserName:%i" where %i is the uid
packet.SetFilePos(::strlen("qUserName:"));
@@ -435,8 +444,7 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName(
return SendPacketNoLock(response.GetString());
}
}
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
#endif
return SendErrorResponse(5);
}
@@ -500,19 +508,32 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
packet.GetHexByteStringTerminatedBy(path, ',');
if (!path.empty()) {
if (packet.GetChar() == ',') {
- uint32_t flags = packet.GetHexMaxU32(false, 0);
+ // FIXME
+ // The flag values for OpenOptions do not match the values used by GDB
+ // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
+ // * rdar://problem/46788934
+ auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0));
if (packet.GetChar() == ',') {
mode_t mode = packet.GetHexMaxU32(false, 0600);
FileSpec path_spec(path);
FileSystem::Instance().Resolve(path_spec);
- File file;
// Do not close fd.
- Status error =
- FileSystem::Instance().Open(file, path_spec, flags, mode, false);
- const int save_errno = error.GetError();
+ auto file = FileSystem::Instance().Open(path_spec, flags, mode, false);
+
+ int save_errno = 0;
+ int descriptor = File::kInvalidDescriptor;
+ if (file) {
+ descriptor = file.get()->GetDescriptor();
+ } else {
+ std::error_code code = errorToErrorCode(file.takeError());
+ if (code.category() == std::system_category()) {
+ save_errno = code.value();
+ }
+ }
+
StreamString response;
response.PutChar('F');
- response.Printf("%i", file.GetDescriptor());
+ response.Printf("%i", descriptor);
if (save_errno)
response.Printf(",%i", save_errno);
return SendPacketNoLock(response.GetString());
@@ -530,7 +551,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
int err = -1;
int save_errno = 0;
if (fd >= 0) {
- File file(fd, true);
+ NativeFile file(fd, File::OpenOptions(0), true);
Status error = file.Close();
err = 0;
save_errno = error.GetError();
@@ -552,16 +573,16 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
packet.SetFilePos(::strlen("vFile:pread:"));
int fd = packet.GetS32(-1);
if (packet.GetChar() == ',') {
- size_t count = packet.GetU64(UINT64_MAX);
+ size_t count = packet.GetU64(SIZE_MAX);
if (packet.GetChar() == ',') {
off_t offset = packet.GetU64(UINT32_MAX);
- if (count == UINT64_MAX) {
+ if (count == SIZE_MAX) {
response.Printf("F-1:%i", EINVAL);
return SendPacketNoLock(response.GetString());
}
std::string buffer(count, 0);
- File file(fd, false);
+ NativeFile file(fd, File::eOpenOptionRead, false);
Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
const ssize_t bytes_read = error.Success() ? count : -1;
const int save_errno = error.GetError();
@@ -593,7 +614,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
if (packet.GetChar() == ',') {
std::string buffer;
if (packet.GetEscapedBinaryData(buffer)) {
- File file(fd, false);
+ NativeFile file(fd, File::eOpenOptionWrite, false);
size_t count = buffer.size();
Status error =
file.Write(static_cast<const void *>(&buffer[0]), count, offset);
@@ -825,6 +846,7 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported(
#if defined(__linux__) || defined(__NetBSD__)
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
+ response.PutCString(";qXfer:libraries-svr4:read+");
#endif
return SendPacketNoLock(response.GetString());
@@ -1016,9 +1038,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
m_process_launch_info.GetExecutableFile().SetFile(
arg, FileSpec::Style::native);
m_process_launch_info.GetArguments().AppendArgument(arg);
- if (log)
- log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
- __FUNCTION__, actual_arg_index, arg.c_str());
+ LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"",
+ __FUNCTION__, actual_arg_index, arg.c_str());
++actual_arg_index;
}
}
@@ -1104,6 +1125,8 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
StringExtractorGDBRemote &packet) {
+ namespace json = llvm::json;
+
packet.SetFilePos(::strlen("jModulesInfo:"));
StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());
@@ -1114,7 +1137,7 @@ GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
if (!packet_array)
return SendErrorResponse(2);
- JSONArray::SP response_array_sp = std::make_shared<JSONArray>();
+ json::Array response_array;
for (size_t i = 0; i < packet_array->GetSize(); ++i) {
StructuredData::Dictionary *query =
packet_array->GetItemAtIndex(i)->GetAsDictionary();
@@ -1132,27 +1155,22 @@ GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
const auto file_offset = matched_module_spec.GetObjectOffset();
const auto file_size = matched_module_spec.GetObjectSize();
const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
-
if (uuid_str.empty())
continue;
-
- JSONObject::SP response = std::make_shared<JSONObject>();
- response_array_sp->AppendObject(response);
- response->SetObject("uuid", std::make_shared<JSONString>(uuid_str));
- response->SetObject(
- "triple",
- std::make_shared<JSONString>(
- matched_module_spec.GetArchitecture().GetTriple().getTriple()));
- response->SetObject("file_path",
- std::make_shared<JSONString>(
- matched_module_spec.GetFileSpec().GetPath()));
- response->SetObject("file_offset",
- std::make_shared<JSONNumber>(file_offset));
- response->SetObject("file_size", std::make_shared<JSONNumber>(file_size));
+ const auto triple_str =
+ matched_module_spec.GetArchitecture().GetTriple().getTriple();
+ const auto file_path = matched_module_spec.GetFileSpec().GetPath();
+
+ json::Object response{{"uuid", uuid_str},
+ {"triple", triple_str},
+ {"file_path", file_path},
+ {"file_offset", static_cast<int64_t>(file_offset)},
+ {"file_size", static_cast<int64_t>(file_size)}};
+ response_array.push_back(std::move(response));
}
StreamString response;
- response_array_sp->Write(response);
+ response.AsRawOstream() << std::move(response_array);
StreamGDBRemote escaped_response;
escaped_response.PutEscapedBytes(response.GetString().data(),
response.GetSize());
@@ -1168,6 +1186,15 @@ void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
response.PutCString("name:");
response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+
+ response.PutChar(';');
+ response.PutCString("args:");
+ response.PutStringAsRawHex8(proc_info.GetArg0());
+ for (auto &arg : proc_info.GetArguments()) {
+ response.PutChar('-');
+ response.PutStringAsRawHex8(arg.ref());
+ }
+
response.PutChar(';');
const ArchSpec &proc_arch = proc_info.GetArchitecture();
if (proc_arch.IsValid()) {
@@ -1217,6 +1244,7 @@ void GDBRemoteCommunicationServerCommon::
case llvm::Triple::arm:
case llvm::Triple::thumb:
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
ostype = "ios";
break;
default:
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 196607665bba..ad1a39b57969 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -11,7 +11,7 @@
#include "lldb/Host/Config.h"
#include "GDBRemoteCommunicationServerLLGS.h"
-#include "lldb/Utility/StreamGDBRemote.h"
+#include "lldb/Utility/GDBRemote.h"
#include <chrono>
#include <cstring>
@@ -32,7 +32,6 @@
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Endian.h"
-#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
@@ -40,6 +39,7 @@
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/UriParser.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/ScopedPrinter.h"
#include "ProcessGDBRemote.h"
@@ -217,8 +217,13 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
if (should_forward_stdio) {
+ // Temporarily relax the following for Windows until we can take advantage
+ // of the recently added pty support. This doesn't really affect the use of
+ // lldb-server on Windows.
+#if !defined(_WIN32)
if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection())
return Status(std::move(Err));
+#endif
}
{
@@ -249,18 +254,18 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
// Setup stdout/stderr mapping from inferior to $O
auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
if (terminal_fd >= 0) {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
- "inferior STDIO fd to %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
Status status = SetSTDIOFileDescriptor(terminal_fd);
if (status.Fail())
return status;
} else {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
- "inferior STDIO since terminal fd reported as %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
}
} else {
LLDB_LOG(log,
@@ -278,9 +283,8 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
- __FUNCTION__, pid);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
+ __FUNCTION__, pid);
// Before we try to attach, make sure we aren't already monitoring something
// else.
@@ -304,18 +308,18 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
// Setup stdout/stderr mapping from inferior.
auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
if (terminal_fd >= 0) {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
- "inferior STDIO fd to %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
Status status = SetSTDIOFileDescriptor(terminal_fd);
if (status.Fail())
return status;
} else {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
- "inferior STDIO since terminal fd reported as %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
}
printf("Attached to process %" PRIu64 "...\n", pid);
@@ -327,10 +331,11 @@ void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
- "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
- __FUNCTION__, process->GetID(),
- StateAsCString(process->GetState()));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
+ __FUNCTION__, process->GetID(),
+ StateAsCString(process->GetState()));
}
}
@@ -397,19 +402,21 @@ static void WriteRegisterValueInHexFixedWidth(
}
}
-static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
+static llvm::Expected<json::Object>
+GetRegistersAsJSON(NativeThreadProtocol &thread) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
NativeRegisterContext& reg_ctx = thread.GetRegisterContext();
- JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
+ json::Object register_object;
#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
// Expedite all registers in the first register set (i.e. should be GPRs)
// that are not contained in other registers.
const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
if (!reg_set_p)
- return nullptr;
+ return llvm::make_error<llvm::StringError>("failed to get registers",
+ llvm::inconvertibleErrorCode());
for (const uint32_t *reg_num_p = reg_set_p->registers;
*reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
uint32_t reg_num = *reg_num_p;
@@ -431,10 +438,9 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
const RegisterInfo *const reg_info_p =
reg_ctx.GetRegisterInfoAtIndex(reg_num);
if (reg_info_p == nullptr) {
- if (log)
- log->Printf(
- "%s failed to get register info for register index %" PRIu32,
- __FUNCTION__, reg_num);
+ LLDB_LOGF(log,
+ "%s failed to get register info for register index %" PRIu32,
+ __FUNCTION__, reg_num);
continue;
}
@@ -445,11 +451,10 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
RegisterValue reg_value;
Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
- __FUNCTION__,
- reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
- reg_num, error.AsCString());
+ LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__,
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ reg_num, error.AsCString());
continue;
}
@@ -457,12 +462,11 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p,
&reg_value, lldb::eByteOrderBig);
- register_object_sp->SetObject(
- llvm::to_string(reg_num),
- std::make_shared<JSONString>(stream.GetString()));
+ register_object.try_emplace(llvm::to_string(reg_num),
+ stream.GetString().str());
}
- return register_object_sp;
+ return register_object;
}
static const char *GetStopReasonString(StopReason stop_reason) {
@@ -489,11 +493,11 @@ static const char *GetStopReasonString(StopReason stop_reason) {
return nullptr;
}
-static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
- bool abridged) {
+static llvm::Expected<json::Array>
+GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
+ json::Array threads_array;
// Ensure we can get info on the given thread.
uint32_t thread_idx = 0;
@@ -507,61 +511,62 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
struct ThreadStopInfo tid_stop_info;
std::string description;
if (!thread->GetStopReason(tid_stop_info, description))
- return nullptr;
+ return llvm::make_error<llvm::StringError>(
+ "failed to get stop reason", llvm::inconvertibleErrorCode());
const int signum = tid_stop_info.details.signal.signo;
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " tid %" PRIu64
- " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
- __FUNCTION__, process.GetID(), tid, signum,
- tid_stop_info.reason, tid_stop_info.details.exception.type);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64
+ " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ __FUNCTION__, process.GetID(), tid, signum,
+ tid_stop_info.reason, tid_stop_info.details.exception.type);
}
- JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
- threads_array_sp->AppendObject(thread_obj_sp);
+ json::Object thread_obj;
if (!abridged) {
- if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread))
- thread_obj_sp->SetObject("registers", registers_sp);
+ if (llvm::Expected<json::Object> registers =
+ GetRegistersAsJSON(*thread)) {
+ thread_obj.try_emplace("registers", std::move(*registers));
+ } else {
+ return registers.takeError();
+ }
}
- thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
+ thread_obj.try_emplace("tid", static_cast<int64_t>(tid));
+
if (signum != 0)
- thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
+ thread_obj.try_emplace("signal", signum);
const std::string thread_name = thread->GetName();
if (!thread_name.empty())
- thread_obj_sp->SetObject("name",
- std::make_shared<JSONString>(thread_name));
+ thread_obj.try_emplace("name", thread_name);
- if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
- thread_obj_sp->SetObject("reason",
- std::make_shared<JSONString>(stop_reason_str));
+ const char *stop_reason = GetStopReasonString(tid_stop_info.reason);
+ if (stop_reason)
+ thread_obj.try_emplace("reason", stop_reason);
if (!description.empty())
- thread_obj_sp->SetObject("description",
- std::make_shared<JSONString>(description));
+ thread_obj.try_emplace("description", description);
if ((tid_stop_info.reason == eStopReasonException) &&
tid_stop_info.details.exception.type) {
- thread_obj_sp->SetObject(
- "metype",
- std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
+ thread_obj.try_emplace(
+ "metype", static_cast<int64_t>(tid_stop_info.details.exception.type));
- JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
+ json::Array medata_array;
for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count;
++i) {
- medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
- tid_stop_info.details.exception.data[i]));
+ medata_array.push_back(
+ static_cast<int64_t>(tid_stop_info.details.exception.data[i]));
}
- thread_obj_sp->SetObject("medata", medata_array_sp);
+ thread_obj.try_emplace("medata", std::move(medata_array));
}
-
- // TODO: Expedite interesting regions of inferior memory
+ threads_array.push_back(std::move(thread_obj));
}
-
- return threads_array_sp;
+ return threads_array;
}
GDBRemoteCommunication::PacketResult
@@ -653,19 +658,21 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
// is hex ascii JSON that contains the thread IDs thread stop info only for
// threads that have stop reasons. Only send this if we have more than one
// thread otherwise this packet has all the info it needs.
- if (thread_index > 0) {
+ if (thread_index > 1) {
const bool threads_with_valid_stop_info_only = true;
- JSONArray::SP threads_info_sp = GetJSONThreadsInfo(
+ llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo(
*m_debugged_process_up, threads_with_valid_stop_info_only);
- if (threads_info_sp) {
+ if (threads_info) {
response.PutCString("jstopinfo:");
StreamString unescaped_response;
- threads_info_sp->Write(unescaped_response);
+ unescaped_response.AsRawOstream() << std::move(*threads_info);
response.PutStringAsRawHex8(unescaped_response.GetData());
response.PutChar(';');
- } else
- LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}",
- m_debugged_process_up->GetID());
+ } else {
+ LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}:",
+ m_debugged_process_up->GetID(),
+ llvm::toString(threads_info.takeError()));
+ }
}
uint32_t i = 0;
@@ -684,12 +691,10 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
RegisterValue reg_value;
Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
- __FUNCTION__,
- reg_info_p->name ? reg_info_p->name
- : "<unnamed-register>",
- reg_to_read, error.AsCString());
+ LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__,
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ reg_to_read, error.AsCString());
continue;
}
@@ -713,25 +718,24 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
const RegisterSet *reg_set_p;
if (reg_ctx.GetRegisterSetCount() > 0 &&
((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
- "from set '%s' (registers set count: %zu)",
- __FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- reg_set_p->num_registers);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s expediting registers "
+ "from set '%s' (registers set count: %zu)",
+ __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ reg_set_p->num_registers);
for (const uint32_t *reg_num_p = reg_set_p->registers;
*reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
const RegisterInfo *const reg_info_p =
reg_ctx.GetRegisterInfoAtIndex(*reg_num_p);
if (reg_info_p == nullptr) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
- "register info for register set '%s', register index "
- "%" PRIu32,
- __FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- *reg_num_p);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to get "
+ "register info for register set '%s', register index "
+ "%" PRIu32,
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ *reg_num_p);
} else if (reg_info_p->value_regs == nullptr) {
// Only expediate registers that are not contained in other registers.
RegisterValue reg_value;
@@ -742,13 +746,12 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
&reg_value, lldb::eByteOrderBig);
response.PutChar(';');
} else {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
- "register '%s' index %" PRIu32 ": %s",
- __FUNCTION__,
- reg_info_p->name ? reg_info_p->name
- : "<unnamed-register>",
- *reg_num_p, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__,
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ *reg_num_p, error.AsCString());
}
}
}
@@ -787,15 +790,14 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
PacketResult result = SendStopReasonForState(StateType::eStateExited);
if (result != PacketResult::Success) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
- "notification for PID %" PRIu64 ", state: eStateExited",
- __FUNCTION__, process->GetID());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
}
// Close the pipe to the inferior terminal i/o if we launched it and set one
@@ -812,8 +814,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
// Send the stop reason unless this is the stop after the launch or attach.
switch (m_inferior_prev_state) {
@@ -825,10 +826,10 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
// In all other cases, send the stop reason.
PacketResult result = SendStopReasonForState(StateType::eStateStopped);
if (result != PacketResult::Success) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
- "notification for PID %" PRIu64 ", state: eStateExited",
- __FUNCTION__, process->GetID());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
}
break;
}
@@ -839,9 +840,10 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
- "NativeProcessProtocol pid %" PRIu64 ", state: %s",
- __FUNCTION__, process->GetID(), StateAsCString(state));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
}
switch (state) {
@@ -868,9 +870,10 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
default:
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state "
- "change for pid %" PRIu64 ", new state: %s",
- __FUNCTION__, process->GetID(), StateAsCString(state));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s didn't handle state "
+ "change for pid %" PRIu64 ", new state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
}
break;
}
@@ -888,10 +891,10 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
if (!m_handshake_completed) {
if (!HandshakeWithClient()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with "
- "client failed, exiting",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s handshake with "
+ "client failed, exiting",
+ __FUNCTION__);
m_mainloop.RequestTermination();
return;
}
@@ -908,10 +911,10 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
break; // No more packets in the queue
if ((result != PacketResult::Success)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet "
- "failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s processing a packet "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
m_mainloop.RequestTermination();
break;
}
@@ -982,9 +985,10 @@ void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
// Not much we can do about the failure. Log it and continue without
// forwarding.
if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
- "forwarding: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
+ "forwarding: %s",
+ __FUNCTION__, error.AsCString());
}
}
@@ -1008,10 +1012,11 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
case eConnectionStatusError:
case eConnectionStatusNoConnection:
if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
- "forwarding as communication returned status %d (error: "
- "%s)",
- __FUNCTION__, status, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
+ "forwarding as communication returned status %d (error: "
+ "%s)",
+ __FUNCTION__, status, error.AsCString());
m_stdio_handle_up.reset();
return;
@@ -1349,15 +1354,14 @@ GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
// Ensure we have a native process.
if (!m_debugged_process_up) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
- "shared pointer",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
return SendErrorResponse(0x36);
}
@@ -1376,13 +1380,14 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
if (packet.GetBytesLeft() > 0) {
// FIXME add continue at address support for $C{signo}[;{continue-address}].
if (*packet.Peek() == ';')
- return SendUnimplementedResponse(packet.GetStringRef().c_str());
+ return SendUnimplementedResponse(packet.GetStringRef().data());
else
return SendIllFormedResponse(
packet, "unexpected content after $C{signal-number}");
}
- ResumeActionList resume_actions(StateType::eStateRunning, 0);
+ ResumeActionList resume_actions(StateType::eStateRunning,
+ LLDB_INVALID_SIGNAL_NUMBER);
Status error;
// We have two branches: what to do if a continue thread is specified (in
@@ -1430,8 +1435,7 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
packet.SetFilePos(packet.GetFilePos() + ::strlen("c"));
@@ -1440,20 +1444,21 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
if (has_continue_address) {
LLDB_LOG(log, "not implemented for c[address] variant [{0} remains]",
packet.Peek());
- return SendUnimplementedResponse(packet.GetStringRef().c_str());
+ return SendUnimplementedResponse(packet.GetStringRef().data());
}
// Ensure we have a native process.
if (!m_debugged_process_up) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
- "shared pointer",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
return SendErrorResponse(0x36);
}
// Build the ResumeActionList
- ResumeActionList actions(StateType::eStateRunning, 0);
+ ResumeActionList actions(StateType::eStateRunning,
+ LLDB_INVALID_SIGNAL_NUMBER);
Status error = m_debugged_process_up->Resume(actions);
if (error.Fail()) {
@@ -1480,17 +1485,16 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vCont(
StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
+ __FUNCTION__);
packet.SetFilePos(::strlen("vCont"));
if (packet.GetBytesLeft() == 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s missing action from "
- "vCont package",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s missing action from "
+ "vCont package",
+ __FUNCTION__);
return SendIllFormedResponse(packet, "Missing action from vCont package");
}
@@ -1521,7 +1525,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont(
ResumeAction thread_action;
thread_action.tid = LLDB_INVALID_THREAD_ID;
thread_action.state = eStateInvalid;
- thread_action.signal = 0;
+ thread_action.signal = LLDB_INVALID_SIGNAL_NUMBER;
const char action = packet.GetChar();
switch (action) {
@@ -1958,10 +1962,10 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
const uint32_t reg_index =
packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
if (reg_index == std::numeric_limits<uint32_t>::max()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
- "parse register number from request \"%s\"",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().data());
return SendErrorResponse(0x15);
}
@@ -1978,20 +1982,19 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
// Return the end of registers response if we've iterated one past the end of
// the register set.
if (reg_index >= reg_context.GetUserRegisterCount()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " beyond register count %" PRIu32,
- __FUNCTION__, reg_index,
- reg_context.GetUserRegisterCount());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
return SendErrorResponse(0x15);
}
const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " returned NULL",
- __FUNCTION__, reg_index);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
return SendErrorResponse(0x15);
}
@@ -2002,20 +2005,20 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
RegisterValue reg_value;
Status error = reg_context.ReadRegister(reg_info, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
- "requested register %" PRIu32 " (%s) failed: %s",
- __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, read of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
return SendErrorResponse(0x15);
}
const uint8_t *const data =
reinterpret_cast<const uint8_t *>(reg_value.GetBytes());
if (!data) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get data "
- "bytes from requested register %" PRIu32,
- __FUNCTION__, reg_index);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to get data "
+ "bytes from requested register %" PRIu32,
+ __FUNCTION__, reg_index);
return SendErrorResponse(0x15);
}
@@ -2039,10 +2042,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
const uint32_t reg_index =
packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
if (reg_index == std::numeric_limits<uint32_t>::max()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
- "parse register number from request \"%s\"",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().data());
return SendErrorResponse(0x29);
}
@@ -2058,10 +2061,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Get the thread to use.
NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
if (!thread) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
- "available (thread index 0)",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no thread "
+ "available (thread index 0)",
+ __FUNCTION__);
return SendErrorResponse(0x28);
}
@@ -2069,20 +2072,20 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
NativeRegisterContext &reg_context = thread->GetRegisterContext();
const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " returned NULL",
- __FUNCTION__, reg_index);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
return SendErrorResponse(0x48);
}
// Return the end of registers response if we've iterated one past the end of
// the register set.
if (reg_index >= reg_context.GetUserRegisterCount()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " beyond register count %" PRIu32,
- __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
return SendErrorResponse(0x47);
}
@@ -2101,10 +2104,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
m_debugged_process_up->GetArchitecture().GetByteOrder());
Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
- "requested register %" PRIu32 " (%s) failed: %s",
- __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, write of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
return SendErrorResponse(0x32);
}
@@ -2118,20 +2121,20 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
// Parse out which variant of $H is requested.
packet.SetFilePos(strlen("H"));
if (packet.GetBytesLeft() < 1) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, H command "
- "missing {g,c} variant",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, H command "
+ "missing {g,c} variant",
+ __FUNCTION__);
return SendIllFormedResponse(packet, "H command missing {g,c} variant");
}
@@ -2144,10 +2147,10 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
break;
default:
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
- __FUNCTION__, h_variant);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
+ __FUNCTION__, h_variant);
return SendIllFormedResponse(packet,
"H variant unsupported, should be c or g");
}
@@ -2162,10 +2165,10 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
if (!thread) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
- " not found",
- __FUNCTION__, tid);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
+ " not found",
+ __FUNCTION__, tid);
return SendErrorResponse(0x15);
}
}
@@ -2196,10 +2199,10 @@ GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2257,10 +2260,10 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2284,10 +2287,10 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
if (byte_count == 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: "
- "zero-length packet",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s nothing to read: "
+ "zero-length packet",
+ __FUNCTION__);
return SendOKResponse();
}
@@ -2301,20 +2304,20 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
Status error = m_debugged_process_up->ReadMemoryWithoutTrap(
read_addr, &buf[0], byte_count, bytes_read);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " mem 0x%" PRIx64 ": failed to read. Error: %s",
- __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": failed to read. Error: %s",
+ __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
+ error.AsCString());
return SendErrorResponse(0x08);
}
if (bytes_read == 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
- __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
- byte_count);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
+ __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
+ byte_count);
return SendErrorResponse(0x08);
}
@@ -2338,10 +2341,10 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2426,10 +2429,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
// since we won't have a NativeProcessProtocol.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2454,10 +2457,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
// Ensure we have a process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2703,10 +2706,10 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
// Ensure we have a process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x32);
}
@@ -2725,7 +2728,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
return SendErrorResponse(0x33);
// Create the step action for the given thread.
- ResumeAction action = {tid, eStateStepping, 0};
+ ResumeAction action = {tid, eStateStepping, LLDB_INVALID_SIGNAL_NUMBER};
// Setup the actions list.
ResumeActionList actions;
@@ -2735,11 +2738,11 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
Status error = m_debugged_process_up->Resume(actions);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " tid %" PRIu64 " Resume() failed with error: %s",
- __FUNCTION__, m_debugged_process_up->GetID(), tid,
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64 " Resume() failed with error: %s",
+ __FUNCTION__, m_debugged_process_up->GetID(), tid,
+ error.AsCString());
return SendErrorResponse(0x49);
}
@@ -2765,6 +2768,24 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
return std::move(*buffer_or_error);
}
+ if (object == "libraries-svr4") {
+ auto library_list = m_debugged_process_up->GetLoadedSVR4Libraries();
+ if (!library_list)
+ return library_list.takeError();
+
+ StreamString response;
+ response.Printf("<library-list-svr4 version=\"1.0\">");
+ for (auto const &library : *library_list) {
+ response.Printf("<library name=\"%s\" ",
+ XMLEncodeAttributeValue(library.name.c_str()).c_str());
+ response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map);
+ response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr);
+ response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr);
+ }
+ response.Printf("</library-list-svr4>");
+ return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__);
+ }
+
return llvm::make_error<PacketUnimplementedError>(
"Xfer object not supported");
}
@@ -2968,18 +2989,18 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
"vAttach failed to parse the process id");
// Attempt to attach.
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
- "pid %" PRIu64,
- __FUNCTION__, pid);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
+ "pid %" PRIu64,
+ __FUNCTION__, pid);
Status error = AttachToProcess(pid);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to "
- "pid %" PRIu64 ": %s\n",
- __FUNCTION__, pid, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to attach to "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, pid, error.AsCString());
return SendErrorResponse(error);
}
@@ -2996,10 +3017,10 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -3023,11 +3044,10 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
const Status error = m_debugged_process_up->Detach();
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from "
- "pid %" PRIu64 ": %s\n",
- __FUNCTION__, m_debugged_process_up->GetID(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to detach from "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, m_debugged_process_up->GetID(), error.AsCString());
return SendErrorResponse(0x01);
}
@@ -3042,10 +3062,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
packet.SetFilePos(strlen("qThreadStopInfo"));
const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
if (tid == LLDB_INVALID_THREAD_ID) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
- "parse thread id from request \"%s\"",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse thread id from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().data());
return SendErrorResponse(0x15);
}
return SendStopReplyPacketForThread(tid);
@@ -3064,15 +3084,16 @@ GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
StreamString response;
const bool threads_with_valid_stop_info_only = false;
- JSONArray::SP threads_array_sp = GetJSONThreadsInfo(
+ llvm::Expected<json::Value> threads_info = GetJSONThreadsInfo(
*m_debugged_process_up, threads_with_valid_stop_info_only);
- if (!threads_array_sp) {
- LLDB_LOG(log, "failed to prepare a packet for pid {0}",
- m_debugged_process_up->GetID());
+ if (!threads_info) {
+ LLDB_LOG(log, "failed to prepare a packet for pid {0}: {1}",
+ m_debugged_process_up->GetID(),
+ llvm::toString(threads_info.takeError()));
return SendErrorResponse(52);
}
- threads_array_sp->Write(response);
+ response.AsRawOstream() << *threads_info;
StreamGDBRemote escaped_response;
escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
return SendPacketNoLock(escaped_response.GetString());
@@ -3177,15 +3198,15 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
connection->Disconnect(&error);
if (error.Success()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
- "terminal stdio - SUCCESS",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - SUCCESS",
+ __FUNCTION__);
} else {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
- "terminal stdio - FAIL: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - FAIL: %s",
+ __FUNCTION__, error.AsCString());
}
}
}
@@ -3215,11 +3236,11 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
// Parse out the ';'.
if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
- "error: expected ';' prior to start of thread suffix: packet "
- "contents = '%s'",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected ';' prior to start of thread suffix: packet "
+ "contents = '%s'",
+ __FUNCTION__, packet.GetStringRef().data());
return nullptr;
}
@@ -3228,11 +3249,11 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
// Parse out thread: portion.
if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
- "error: expected 'thread:' but not found, packet contents = "
- "'%s'",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected 'thread:' but not found, packet contents = "
+ "'%s'",
+ __FUNCTION__, packet.GetStringRef().data());
return nullptr;
}
packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
@@ -3283,3 +3304,28 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
}
+
+std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue(
+ llvm::StringRef value) {
+ std::string result;
+ for (const char &c : value) {
+ switch (c) {
+ case '\'':
+ result += "&apos;";
+ break;
+ case '"':
+ result += "&quot;";
+ break;
+ case '<':
+ result += "&lt;";
+ break;
+ case '>':
+ result += "&gt;";
+ break;
+ default:
+ result += c;
+ break;
+ }
+ }
+ return result;
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 068ea52caaaf..088ba92ad11a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -196,6 +196,8 @@ protected:
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
ReadXferObject(llvm::StringRef object, llvm::StringRef annex);
+ static std::string XMLEncodeAttributeValue(llvm::StringRef value);
+
private:
void HandleInferiorState_Exited(NativeProcessProtocol *process);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 6deb75f2f021..25cebbba8f7b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -15,8 +15,10 @@
#include <cstring>
#include <mutex>
#include <sstream>
+#include <thread>
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/Threading.h"
#include "lldb/Host/Config.h"
@@ -26,9 +28,8 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/JSON.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UriParser.h"
@@ -36,8 +37,8 @@
#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
-using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private;
// GDBRemoteCommunicationServerPlatform constructor
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
@@ -104,8 +105,8 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
hostname = "127.0.0.1";
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
+ LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(),
+ port);
// Do not run in a new session so that it can not linger after the platform
// closes.
@@ -161,9 +162,8 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
// process...
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called",
+ __FUNCTION__);
ConnectionFileDescriptor file_conn;
std::string hostname;
@@ -183,17 +183,17 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
Status error =
LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
- "launch failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launch failed: %s",
+ __FUNCTION__, error.AsCString());
return SendErrorResponse(9);
}
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
- "launched successfully as pid %" PRIu64,
- __FUNCTION__, debugserver_pid);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launched successfully as pid %" PRIu64,
+ __FUNCTION__, debugserver_pid);
StreamGDBRemote response;
response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
@@ -215,22 +215,21 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
StringExtractorGDBRemote &packet) {
+ namespace json = llvm::json;
+
if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
return SendErrorResponse(4);
- JSONObject::SP server_sp = std::make_shared<JSONObject>();
- server_sp->SetObject("port",
- std::make_shared<JSONNumber>(m_pending_gdb_server.port));
+ json::Object server{{"port", m_pending_gdb_server.port}};
+
if (!m_pending_gdb_server.socket_name.empty())
- server_sp->SetObject(
- "socket_name",
- std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
+ server.try_emplace("socket_name", m_pending_gdb_server.socket_name);
- JSONArray server_list;
- server_list.AppendObject(server_sp);
+ json::Array server_list;
+ server_list.push_back(std::move(server));
StreamGDBRemote response;
- server_list.Write(response);
+ response.AsRawOstream() << std::move(server_list);
StreamGDBRemote escaped_response;
escaped_response.PutEscapedBytes(response.GetString().data(),
@@ -281,10 +280,9 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
return true;
}
}
- usleep(10000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
- // check one more time after the final usleep
{
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
@@ -303,10 +301,10 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
return true;
}
}
- usleep(10000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
- // check one more time after the final usleep Scope for locker
+ // check one more time after the final sleep
{
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index a77e659a55fa..c06c9527708e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -206,11 +206,14 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
} else {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
GDBR_LOG_PACKETS));
- if (log)
- log->Printf ("error: GDBRemoteRegisterContext::ReadRegisterBytes tried to read the "
- "entire register context at once, expected at least %" PRId64 " bytes "
- "but only got %" PRId64 " bytes.", m_reg_data.GetByteSize(),
- buffer_sp->GetByteSize());
+ LLDB_LOGF(
+ log,
+ "error: GDBRemoteRegisterContext::ReadRegisterBytes tried "
+ "to read the "
+ "entire register context at once, expected at least %" PRId64
+ " bytes "
+ "but only got %" PRId64 " bytes.",
+ m_reg_data.GetByteSize(), buffer_sp->GetByteSize());
}
}
return false;
@@ -390,13 +393,15 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
if (log->GetVerbose()) {
StreamString strm;
gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write register for \"%s\":\n%s",
- reg_info->name, strm.GetData());
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\":\n%s",
+ reg_info->name, strm.GetData());
} else
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write register for \"%s\"",
- reg_info->name);
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\"",
+ reg_info->name);
}
}
}
@@ -494,12 +499,14 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
if (log->GetVerbose()) {
StreamString strm;
gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "read all registers:\n%s",
- strm.GetData());
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "read all registers:\n%s",
+ strm.GetData());
} else
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "read all registers");
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "read all registers");
}
}
@@ -630,7 +637,9 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
if (m_thread.GetProcess().get()) {
const ArchSpec &arch =
m_thread.GetProcess()->GetTarget().GetArchitecture();
- if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 &&
+ if (arch.IsValid() &&
+ (arch.GetMachine() == llvm::Triple::aarch64 ||
+ arch.GetMachine() == llvm::Triple::aarch64_32) &&
arch.GetTriple().getVendor() == llvm::Triple::Apple &&
arch.GetTriple().getOS() == llvm::Triple::IOS) {
arm64_debugserver = true;
@@ -667,12 +676,14 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
if (log->GetVerbose()) {
StreamString strm;
gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write all registers:\n%s",
- strm.GetData());
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write all registers:\n%s",
+ strm.GetData());
} else
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write all registers");
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write all registers");
}
}
return false;
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index a6fdd8dd0707..f1762abc55f8 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -63,7 +63,6 @@
#include "lldb/Target/TargetList.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Utility/Args.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/State.h"
@@ -81,12 +80,12 @@
#include "lldb/Host/Host.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUGSERVER_BASENAME "debugserver"
-using namespace llvm;
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
@@ -99,51 +98,25 @@ namespace lldb {
// namespace. This allows you to attach with a debugger and call this function
// and get the packet history dumped to a file.
void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
- StreamFile strm;
- Status error = FileSystem::Instance().Open(strm.GetFile(), FileSpec(path),
- File::eOpenOptionWrite |
- File::eOpenOptionCanCreate);
- if (error.Success())
- ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm);
+ auto file = FileSystem::Instance().Open(
+ FileSpec(path), File::eOpenOptionWrite | File::eOpenOptionCanCreate);
+ if (!file) {
+ llvm::consumeError(file.takeError());
+ return;
+ }
+ StreamFile stream(std::move(file.get()));
+ ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(stream);
}
} // namespace lldb
namespace {
-static constexpr PropertyDefinition g_properties[] = {
- {"packet-timeout",
- OptionValue::eTypeUInt64,
- true,
- 5
-#if defined(__has_feature)
-#if __has_feature(address_sanitizer)
- * 2
-#endif
-#endif
- ,
- nullptr,
- {},
- "Specify the default packet timeout in seconds."},
- {"target-definition-file",
- OptionValue::eTypeFileSpec,
- true,
- 0,
- nullptr,
- {},
- "The file that provides the description for remote target registers."},
- {"use-libraries-svr4",
- OptionValue::eTypeBoolean,
- true,
- false,
- nullptr,
- {},
- "If true, the libraries-svr4 feature will be used to get a hold of the "
- "process's loaded modules."}};
+#define LLDB_PROPERTIES_processgdbremote
+#include "ProcessGDBRemoteProperties.inc"
enum {
- ePropertyPacketTimeout,
- ePropertyTargetDefinitionFile,
- ePropertyUseSVR4
+#define LLDB_PROPERTIES_processgdbremote
+#include "ProcessGDBRemotePropertiesEnum.inc"
};
class PluginProperties : public Properties {
@@ -154,7 +127,7 @@ public:
PluginProperties() : Properties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_processgdbremote_properties);
}
~PluginProperties() override {}
@@ -162,7 +135,7 @@ public:
uint64_t GetPacketTimeout() {
const uint32_t idx = ePropertyPacketTimeout;
return m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_processgdbremote_properties[idx].default_uint_value);
}
bool SetPacketTimeout(uint64_t timeout) {
@@ -178,7 +151,8 @@ public:
bool GetUseSVR4() const {
const uint32_t idx = ePropertyUseSVR4;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx,
+ g_processgdbremote_properties[idx].default_uint_value != 0);
}
};
@@ -191,45 +165,6 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
return g_settings_sp;
}
-class ProcessGDBRemoteProvider
- : public repro::Provider<ProcessGDBRemoteProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {
- }
-
- raw_ostream *GetHistoryStream() {
- FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);
-
- std::error_code EC;
- m_stream_up = llvm::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
- sys::fs::OpenFlags::F_Text);
- return m_stream_up.get();
- }
-
- void SetCallback(std::function<void()> callback) {
- m_callback = std::move(callback);
- }
-
- void Keep() override { m_callback(); }
-
- void Discard() override { m_callback(); }
-
- static char ID;
-
-private:
- std::function<void()> m_callback;
- std::unique_ptr<raw_fd_ostream> m_stream_up;
-};
-
-char ProcessGDBRemoteProvider::ID = 0;
-const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
-const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
-
} // namespace
// TODO Randomly assigning a port is unsafe. We should get an unused
@@ -339,8 +274,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
"async thread did exit");
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
- ProcessGDBRemoteProvider &provider =
- g->GetOrCreate<ProcessGDBRemoteProvider>();
+ repro::ProcessGDBRemoteProvider &provider =
+ g->GetOrCreate<repro::ProcessGDBRemoteProvider>();
// Set the history stream to the stream owned by the provider.
m_gdb_comm.SetHistoryStream(provider.GetHistoryStream());
// Make sure to clear the stream again when we're finished.
@@ -354,10 +289,10 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
if (m_async_listener_sp->StartListeningForEvents(
&m_async_broadcaster, async_event_mask) != async_event_mask) {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for "
- "m_async_broadcaster events",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s failed to listen for "
+ "m_async_broadcaster events",
+ __FUNCTION__);
}
const uint32_t gdb_event_mask =
@@ -365,9 +300,9 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
if (m_async_listener_sp->StartListeningForEvents(
&m_gdb_comm, gdb_event_mask) != gdb_event_mask) {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s failed to listen for m_gdb_comm events",
+ __FUNCTION__);
}
const uint64_t timeout_seconds =
@@ -785,15 +720,15 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
pid, remote_url.str().c_str());
}
- if (log)
- log->Printf("ProcessGDBRemote::%s pid %" PRIu64
- ": normalizing target architecture initial triple: %s "
- "(GetTarget().GetArchitecture().IsValid() %s, "
- "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
- __FUNCTION__, GetID(),
- GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
- GetTarget().GetArchitecture().IsValid() ? "true" : "false",
- m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s pid %" PRIu64
+ ": normalizing target architecture initial triple: %s "
+ "(GetTarget().GetArchitecture().IsValid() %s, "
+ "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
+ GetTarget().GetArchitecture().IsValid() ? "true" : "false",
+ m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");
if (error.Success() && !GetTarget().GetArchitecture().IsValid() &&
m_gdb_comm.GetHostArchitecture().IsValid()) {
@@ -805,11 +740,11 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
}
- if (log)
- log->Printf("ProcessGDBRemote::%s pid %" PRIu64
- ": normalized target architecture triple: %s",
- __FUNCTION__, GetID(),
- GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s pid %" PRIu64
+ ": normalized target architecture triple: %s",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
if (error.Success()) {
PlatformSP platform_sp = GetTarget().GetPlatform();
@@ -834,8 +769,7 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Status error;
- if (log)
- log->Printf("ProcessGDBRemote::%s() entered", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s() entered", __FUNCTION__);
uint32_t launch_flags = launch_info.GetFlags().Get();
FileSpec stdin_file_spec{};
@@ -862,15 +796,17 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
if (log) {
if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
- log->Printf("ProcessGDBRemote::%s provided with STDIO paths via "
- "launch_info: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s provided with STDIO paths via "
+ "launch_info: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
else
- log->Printf("ProcessGDBRemote::%s no STDIO paths given via launch_info",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s no STDIO paths given via launch_info",
+ __FUNCTION__);
}
const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
@@ -925,24 +861,23 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
if (!stderr_file_spec)
stderr_file_spec = slave_name;
}
- if (log)
- log->Printf(
- "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
- "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+ LLDB_LOGF(
+ log,
+ "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
+ "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
}
- if (log)
- log->Printf("ProcessGDBRemote::%s final STDIO paths after all "
- "adjustments: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString()
- : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s final STDIO paths after all "
+ "adjustments: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
if (stdin_file_spec)
m_gdb_comm.SetSTDIN(stdin_file_spec);
@@ -988,9 +923,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
}
if (GetID() == LLDB_INVALID_PROCESS_ID) {
- if (log)
- log->Printf("failed to connect to debugserver: %s",
- error.AsCString());
+ LLDB_LOGF(log, "failed to connect to debugserver: %s",
+ error.AsCString());
KillDebugserverProcess();
return error;
}
@@ -1020,8 +954,7 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
}
}
} else {
- if (log)
- log->Printf("failed to connect to debugserver: %s", error.AsCString());
+ LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString());
}
} else {
// Set our user ID to an invalid process ID.
@@ -1040,9 +973,8 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (!connect_url.empty()) {
- if (log)
- log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
- connect_url.str().c_str());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
+ connect_url.str().c_str());
std::unique_ptr<ConnectionFileDescriptor> conn_up(
new ConnectionFileDescriptor());
if (conn_up) {
@@ -1062,7 +994,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
if (retry_count >= max_retry_count)
break;
- usleep(100000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
}
@@ -1116,8 +1048,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__);
if (GetID() != LLDB_INVALID_PROCESS_ID) {
BuildDynamicRegisterInfo(false);
@@ -1130,43 +1061,42 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
if (remote_process_arch.IsValid()) {
process_arch = remote_process_arch;
- if (log)
- log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, "
- "using %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
- process_arch.GetTriple().getTriple().c_str()
- ? process_arch.GetTriple().getTriple().c_str()
- : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s gdb-remote had process architecture, "
+ "using %s %s",
+ __FUNCTION__,
+ process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
} else {
process_arch = m_gdb_comm.GetHostArchitecture();
- if (log)
- log->Printf("ProcessGDBRemote::%s gdb-remote did not have process "
- "architecture, using gdb-remote host architecture %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
- process_arch.GetTriple().getTriple().c_str()
- ? process_arch.GetTriple().getTriple().c_str()
- : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s gdb-remote did not have process "
+ "architecture, using gdb-remote host architecture %s %s",
+ __FUNCTION__,
+ process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
}
if (process_arch.IsValid()) {
const ArchSpec &target_arch = GetTarget().GetArchitecture();
if (target_arch.IsValid()) {
- if (log)
- log->Printf(
- "ProcessGDBRemote::%s analyzing target arch, currently %s %s",
- __FUNCTION__,
- target_arch.GetArchitectureName()
- ? target_arch.GetArchitectureName()
- : "<null>",
- target_arch.GetTriple().getTriple().c_str()
- ? target_arch.GetTriple().getTriple().c_str()
- : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s analyzing target arch, currently %s %s",
+ __FUNCTION__,
+ target_arch.GetArchitectureName()
+ ? target_arch.GetArchitectureName()
+ : "<null>",
+ target_arch.GetTriple().getTriple().c_str()
+ ? target_arch.GetTriple().getTriple().c_str()
+ : "<null>");
// If the remote host is ARM and we have apple as the vendor, then
// ARM executables and shared libraries can have mixed ARM
@@ -1180,16 +1110,16 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
process_arch.GetMachine() == llvm::Triple::thumb) &&
process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {
GetTarget().SetArchitecture(process_arch);
- if (log)
- log->Printf("ProcessGDBRemote::%s remote process is ARM/Apple, "
- "setting target arch to %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
- process_arch.GetTriple().getTriple().c_str()
- ? process_arch.GetTriple().getTriple().c_str()
- : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s remote process is ARM/Apple, "
+ "setting target arch to %s %s",
+ __FUNCTION__,
+ process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
} else {
// Fill in what is missing in the triple
const llvm::Triple &remote_triple = process_arch.GetTriple();
@@ -1211,16 +1141,16 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
}
}
- if (log)
- log->Printf("ProcessGDBRemote::%s final target arch after "
- "adjustments for remote architecture: %s %s",
- __FUNCTION__,
- target_arch.GetArchitectureName()
- ? target_arch.GetArchitectureName()
- : "<null>",
- target_arch.GetTriple().getTriple().c_str()
- ? target_arch.GetTriple().getTriple().c_str()
- : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s final target arch after "
+ "adjustments for remote architecture: %s %s",
+ __FUNCTION__,
+ target_arch.GetArchitectureName()
+ ? target_arch.GetArchitectureName()
+ : "<null>",
+ target_arch.GetTriple().getTriple().c_str()
+ ? target_arch.GetTriple().getTriple().c_str()
+ : "<null>");
} else {
// The target doesn't have a valid architecture yet, set it from the
// architecture we got from the remote GDB server
@@ -1247,8 +1177,7 @@ Status ProcessGDBRemote::DoAttachToProcessWithID(
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Status error;
- if (log)
- log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__);
// Clear out and clean up from any current state
Clear();
@@ -1359,8 +1288,7 @@ Status ProcessGDBRemote::WillResume() {
Status ProcessGDBRemote::DoResume() {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::Resume()");
+ LLDB_LOGF(log, "ProcessGDBRemote::Resume()");
ListenerSP listener_sp(
Listener::MakeListener("gdb-remote.resume-packet-sent"));
@@ -1547,9 +1475,8 @@ Status ProcessGDBRemote::DoResume() {
EventSP event_sp;
if (!m_async_thread.IsJoinable()) {
error.SetErrorString("Trying to resume but the async thread is dead.");
- if (log)
- log->Printf("ProcessGDBRemote::DoResume: Trying to resume but the "
- "async thread is dead.");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Trying to resume but the "
+ "async thread is dead.");
return error;
}
@@ -1560,14 +1487,13 @@ Status ProcessGDBRemote::DoResume() {
if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) {
error.SetErrorString("Resume timed out.");
- if (log)
- log->Printf("ProcessGDBRemote::DoResume: Resume timed out.");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Resume timed out.");
} else if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
error.SetErrorString("Broadcast continue, but the async thread was "
"killed before we got an ack back.");
- if (log)
- log->Printf("ProcessGDBRemote::DoResume: Broadcast continue, but the "
- "async thread was killed before we got an ack back.");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoResume: Broadcast continue, but the "
+ "async thread was killed before we got an ack back.");
return error;
}
}
@@ -1864,8 +1790,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
}
for (const auto &pair : expedited_register_map) {
- StringExtractor reg_value_extractor;
- reg_value_extractor.GetStringRef() = pair.second;
+ StringExtractor reg_value_extractor(pair.second);
DataBufferSP buffer_sp(new DataBufferHeap(
reg_value_extractor.GetStringRef().size() / 2, 0));
reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
@@ -1979,8 +1904,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (watch_id == LLDB_INVALID_WATCH_ID) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf("failed to find watchpoint");
+ LLDB_LOGF(log, "failed to find watchpoint");
}
thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
*thread_sp, watch_id, wp_hit_addr));
@@ -2400,7 +2324,12 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
description = ostr.GetString();
} else if (key.compare("library") == 0) {
- LoadModules();
+ auto error = LoadModules();
+ if (error) {
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ LLDB_LOG_ERROR(log, std::move(error), "Failed to load modules: {0}");
+ }
} else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
uint32_t reg = UINT32_MAX;
if (!key.getAsInteger(16, reg))
@@ -2474,7 +2403,7 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
// Clear the thread stop stack
m_stop_packet_stack.clear();
}
-
+
// If we have queried for a default thread id
if (m_initial_tid != LLDB_INVALID_THREAD_ID) {
m_thread_list.SetSelectedThreadByID(m_initial_tid);
@@ -2501,8 +2430,7 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) {
Status ProcessGDBRemote::DoDetach(bool keep_stopped) {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+ LLDB_LOGF(log, "ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
error = m_gdb_comm.Detach(keep_stopped);
if (log) {
@@ -2510,8 +2438,9 @@ Status ProcessGDBRemote::DoDetach(bool keep_stopped) {
log->PutCString(
"ProcessGDBRemote::DoDetach() detach packet sent successfully");
else
- log->Printf("ProcessGDBRemote::DoDetach() detach packet send failed: %s",
- error.AsCString() ? error.AsCString() : "<unknown error>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
+ error.AsCString() ? error.AsCString() : "<unknown error>");
}
if (!error.Success())
@@ -2530,8 +2459,7 @@ Status ProcessGDBRemote::DoDetach(bool keep_stopped) {
Status ProcessGDBRemote::DoDestroy() {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy()");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy()");
// There is a bug in older iOS debugservers where they don't shut down the
// process they are debugging properly. If the process is sitting at a
@@ -2586,11 +2514,11 @@ Status ProcessGDBRemote::DoDestroy() {
reason = stop_info_sp->GetStopReason();
if (reason == eStopReasonBreakpoint ||
reason == eStopReasonException) {
- if (log)
- log->Printf(
- "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
- " stopped with reason: %s.",
- thread_sp->GetProtocolID(), stop_info_sp->GetDescription());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
+ " stopped with reason: %s.",
+ thread_sp->GetProtocolID(),
+ stop_info_sp->GetDescription());
stop_looks_like_crash = true;
break;
}
@@ -2622,10 +2550,10 @@ Status ProcessGDBRemote::DoDestroy() {
reason = stop_info_sp->GetStopReason();
if (reason != eStopReasonBreakpoint &&
reason != eStopReasonException) {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy() - Suspending "
- "thread: 0x%4.4" PRIx64 " before running.",
- thread_sp->GetProtocolID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy() - Suspending "
+ "thread: 0x%4.4" PRIx64 " before running.",
+ thread_sp->GetProtocolID());
thread_sp->SetResumeState(eStateSuspended);
}
}
@@ -2669,30 +2597,28 @@ Status ProcessGDBRemote::DoDestroy() {
int status;
::pid_t reap_pid;
reap_pid = waitpid(GetID(), &status, WNOHANG);
- if (log)
- log->Printf("Reaped pid: %d, status: %d.\n", reap_pid, status);
+ LLDB_LOGF(log, "Reaped pid: %d, status: %d.\n", reap_pid, status);
}
#endif
SetLastStopPacket(response);
ClearThreadIDList();
exit_status = response.GetHexU8();
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy - got unexpected response "
- "to k packet: %s",
- response.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy - got unexpected response "
+ "to k packet: %s",
+ response.GetStringRef().data());
exit_string.assign("got unexpected response to k packet: ");
exit_string.append(response.GetStringRef());
}
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy - failed to send k packet");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy - failed to send k packet");
exit_string.assign("failed to send the k packet");
}
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy - killed or interrupted while "
- "attaching");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy - killed or interrupted while "
+ "attaching");
exit_string.assign("killed or interrupted while attaching.");
}
} else {
@@ -2715,8 +2641,7 @@ void ProcessGDBRemote::SetLastStopPacket(
response.GetStringRef().find(";reason:exec;") != std::string::npos;
if (did_exec) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+ LLDB_LOGF(log, "ProcessGDBRemote::SetLastStopPacket () - detected exec");
m_thread_list_real.Clear();
m_thread_list.Clear();
@@ -2756,9 +2681,13 @@ addr_t ProcessGDBRemote::GetImageInfoAddress() {
// the loaded module list can also provides a link map address
if (addr == LLDB_INVALID_ADDRESS) {
- LoadedModuleInfoList list;
- if (GetLoadedModuleList(list).Success())
- addr = list.m_link_map;
+ llvm::Expected<LoadedModuleInfoList> list = GetLoadedModuleList();
+ if (!list) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ LLDB_LOG_ERROR(log, list.takeError(), "Failed to read module list: {0}");
+ } else {
+ addr = list->m_link_map;
+ }
}
return addr;
@@ -2840,7 +2769,7 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
else
error.SetErrorStringWithFormat(
"unexpected response to GDB server memory read packet '%s': '%s'",
- packet, response.GetStringRef().c_str());
+ packet, response.GetStringRef().data());
} else {
error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
}
@@ -2950,7 +2879,7 @@ Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) {
else
status.SetErrorStringWithFormat(
"unexpected response to GDB server flash erase packet '%s': '%s'",
- packet.GetData(), response.GetStringRef().c_str());
+ packet.GetData(), response.GetStringRef().data());
}
} else {
status.SetErrorStringWithFormat("failed to send packet: '%s'",
@@ -2978,7 +2907,7 @@ Status ProcessGDBRemote::FlashDone() {
else
status.SetErrorStringWithFormat(
"unexpected response to GDB server flash done packet: '%s'",
- response.GetStringRef().c_str());
+ response.GetStringRef().data());
}
} else {
status.SetErrorStringWithFormat("failed to send flash done packet");
@@ -3041,7 +2970,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
else
error.SetErrorStringWithFormat(
"unexpected response to GDB server memory write packet '%s': '%s'",
- packet.GetData(), response.GetStringRef().c_str());
+ packet.GetData(), response.GetStringRef().data());
} else {
error.SetErrorStringWithFormat("failed to send packet: '%s'",
packet.GetData());
@@ -3078,11 +3007,11 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
m_addr_to_mmap_size[allocated_addr] = size;
else {
allocated_addr = LLDB_INVALID_ADDRESS;
- if (log)
- log->Printf("ProcessGDBRemote::%s no direct stub support for memory "
- "allocation, and InferiorCallMmap also failed - is stub "
- "missing register context save/restore capability?",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s no direct stub support for memory "
+ "allocation, and InferiorCallMmap also failed - is stub "
+ "missing register context save/restore capability?",
+ __FUNCTION__);
}
}
@@ -3173,17 +3102,17 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
const addr_t addr = bp_site->GetLoadAddress();
// Log that a breakpoint was requested
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
- ") address = 0x%" PRIx64,
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64,
+ site_id, (uint64_t)addr);
// Breakpoint already exists and is enabled
if (bp_site->IsEnabled()) {
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
- ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",
+ site_id, (uint64_t)addr);
return error;
}
@@ -3231,8 +3160,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
// We reach here when software breakpoints have been found to be
// unsupported. For future calls to set a breakpoint, we will not attempt
// to set a breakpoint with a type that is known not to be supported.
- if (log)
- log->Printf("Software breakpoints are unsupported");
+ LLDB_LOGF(log, "Software breakpoints are unsupported");
// So we will fall through and try a hardware breakpoint
}
@@ -3270,8 +3198,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
// We will reach here when the stub gives an unsupported response to a
// hardware breakpoint
- if (log)
- log->Printf("Hardware breakpoints are unsupported");
+ LLDB_LOGF(log, "Hardware breakpoints are unsupported");
// Finally we will falling through to a #trap style breakpoint
}
@@ -3293,10 +3220,10 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
addr_t addr = bp_site->GetLoadAddress();
user_id_t site_id = bp_site->GetID();
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
- if (log)
- log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
- ") addr = 0x%8.8" PRIx64,
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ site_id, (uint64_t)addr);
if (bp_site->IsEnabled()) {
const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
@@ -3328,10 +3255,10 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
if (error.Success())
bp_site->SetEnabled(false);
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
- ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+ site_id, (uint64_t)addr);
return error;
}
@@ -3363,14 +3290,13 @@ Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
addr_t addr = wp->GetLoadAddress();
Log *log(
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
+ LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
if (wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
return error;
}
@@ -3403,16 +3329,16 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
addr_t addr = wp->GetLoadAddress();
- if (log)
- log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64,
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ watchID, (uint64_t)addr);
if (!wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
- watchID, (uint64_t)addr);
+ 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.
@@ -3447,8 +3373,7 @@ void ProcessGDBRemote::Clear() {
Status ProcessGDBRemote::DoSignal(int signo) {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::DoSignal (signal = %d)", signo);
+ LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo);
if (!m_gdb_comm.SendAsyncSignal(signo))
error.SetErrorStringWithFormat("failed to send signal %i", signo);
@@ -3460,7 +3385,8 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
return Status("No loader provided.");
// Construct replay history path.
- FileSpec history_file = loader->GetFile<ProcessGDBRemoteProvider::Info>();
+ FileSpec history_file =
+ loader->GetFile<repro::ProcessGDBRemoteProvider::Info>();
if (!history_file)
return Status("No provider for gdb-remote.");
@@ -3556,8 +3482,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
int our_socket = sockets[0];
int gdb_socket = sockets[1];
- CleanUp cleanup_our(close, our_socket);
- CleanUp cleanup_gdb(close, gdb_socket);
+ auto cleanup_our = llvm::make_scope_exit([&]() { close(our_socket); });
+ auto cleanup_gdb = llvm::make_scope_exit([&]() { close(gdb_socket); });
// Don't let any child processes inherit our communication socket
SetCloexecFlag(our_socket);
@@ -3577,7 +3503,7 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
// Our process spawned correctly, we can now set our connection to use
// our end of the socket pair
- cleanup_our.disable();
+ cleanup_our.release();
m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true));
#endif
StartAsyncThread();
@@ -3586,9 +3512,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
if (error.Fail()) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("failed to start debugserver process: %s",
- error.AsCString());
+ LLDB_LOGF(log, "failed to start debugserver process: %s",
+ error.AsCString());
return error;
}
@@ -3614,22 +3539,22 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
const bool handled = true;
- if (log)
- log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
- ", signo=%i (0x%x), exit_status=%i)",
- __FUNCTION__, debugserver_pid, signo, signo, exit_status);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
+ ", signo=%i (0x%x), exit_status=%i)",
+ __FUNCTION__, debugserver_pid, signo, signo, exit_status);
std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
- if (log)
- log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
- static_cast<void *>(process_sp.get()));
+ LLDB_LOGF(log, "ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
+ static_cast<void *>(process_sp.get()));
if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
return handled;
// Sleep for a half a second to make sure our inferior process has time to
// set its exit status before we set it incorrectly when both the debugserver
// and the inferior process shut down.
- usleep(500000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+
// If our process hasn't yet exited, debugserver might have died. If the
// process did exit, then we are reaping it.
const StateType state = process_sp->GetState();
@@ -3692,8 +3617,7 @@ void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) {
bool ProcessGDBRemote::StartAsyncThread() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__);
std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
if (!m_async_thread.IsJoinable()) {
@@ -3709,10 +3633,11 @@ bool ProcessGDBRemote::StartAsyncThread() {
return false;
}
m_async_thread = *async_thread;
- } else if (log)
- log->Printf("ProcessGDBRemote::%s () - Called when Async thread was "
- "already running.",
- __FUNCTION__);
+ } else
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s () - Called when Async thread was "
+ "already running.",
+ __FUNCTION__);
return m_async_thread.IsJoinable();
}
@@ -3720,8 +3645,7 @@ bool ProcessGDBRemote::StartAsyncThread() {
void ProcessGDBRemote::StopAsyncThread() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__);
std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
if (m_async_thread.IsJoinable()) {
@@ -3733,8 +3657,9 @@ void ProcessGDBRemote::StopAsyncThread() {
// Stop the stdio thread
m_async_thread.Join(nullptr);
m_async_thread.Reset();
- } else if (log)
- log->Printf(
+ } else
+ LLDB_LOGF(
+ log,
"ProcessGDBRemote::%s () - Called when Async thread was not running.",
__FUNCTION__);
}
@@ -3768,25 +3693,25 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread starting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread starting...",
+ __FUNCTION__, arg, process->GetID());
EventSP event_sp;
bool done = false;
while (!done) {
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") listener.WaitForEvent (NULL, event_sp)...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp)...",
+ __FUNCTION__, arg, process->GetID());
if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") Got an event of type: %d...",
- __FUNCTION__, arg, process->GetID(), event_type);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") Got an event of type: %d...",
+ __FUNCTION__, arg, process->GetID(), event_type);
switch (event_type) {
case eBroadcastBitAsyncContinue: {
@@ -3797,10 +3722,10 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
const char *continue_cstr =
(const char *)continue_packet->GetBytes();
const size_t continue_cstr_len = continue_packet->GetByteSize();
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got eBroadcastBitAsyncContinue: %s",
- __FUNCTION__, arg, process->GetID(), continue_cstr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncContinue: %s",
+ __FUNCTION__, arg, process->GetID(), continue_cstr);
if (::strstr(continue_cstr, "vAttach") == nullptr)
process->SetPrivateState(eStateRunning);
@@ -3891,18 +3816,18 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
break;
case eBroadcastBitAsyncThreadShouldExit:
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got eBroadcastBitAsyncThreadShouldExit...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncThreadShouldExit...",
+ __FUNCTION__, arg, process->GetID());
done = true;
break;
default:
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
done = true;
break;
}
@@ -3925,27 +3850,27 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
}
default:
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
done = true;
break;
}
}
} else {
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") listener.WaitForEvent (NULL, event_sp) => false",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp) => false",
+ __FUNCTION__, arg, process->GetID());
done = true;
}
}
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread exiting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread exiting...",
+ __FUNCTION__, arg, process->GetID());
return {};
}
@@ -3977,8 +3902,7 @@ bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
// thread when it starts to
// run so I can stop it if that's what I want to do.
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Hit New Thread Notification breakpoint.");
+ LLDB_LOGF(log, "Hit New Thread Notification breakpoint.");
return false;
}
@@ -4023,7 +3947,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (m_thread_create_bp_sp) {
if (log && log->GetVerbose())
- log->Printf("Enabled noticing new thread breakpoint.");
+ LLDB_LOGF(log, "Enabled noticing new thread breakpoint.");
m_thread_create_bp_sp->SetEnabled(true);
} else {
PlatformSP platform_sp(GetTarget().GetPlatform());
@@ -4032,14 +3956,13 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
platform_sp->SetThreadCreationBreakpoint(GetTarget());
if (m_thread_create_bp_sp) {
if (log && log->GetVerbose())
- log->Printf(
- "Successfully created new thread notification breakpoint %i",
+ LLDB_LOGF(
+ log, "Successfully created new thread notification breakpoint %i",
m_thread_create_bp_sp->GetID());
m_thread_create_bp_sp->SetCallback(
ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
} else {
- if (log)
- log->Printf("Failed to create new thread notification breakpoint.");
+ LLDB_LOGF(log, "Failed to create new thread notification breakpoint.");
}
}
}
@@ -4049,7 +3972,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
bool ProcessGDBRemote::StopNoticingNewThreads() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf("Disabling new thread notification breakpoint.");
+ LLDB_LOGF(log, "Disabling new thread notification breakpoint.");
if (m_thread_create_bp_sp)
m_thread_create_bp_sp->SetEnabled(false);
@@ -4325,19 +4248,18 @@ bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,
}
if (!m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
- if (log)
- log->Printf("ProcessGDBRemote::%s - failed to get module info for %s:%s",
- __FUNCTION__, module_file_spec.GetPath().c_str(),
- arch.GetTriple().getTriple().c_str());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s - failed to get module info for %s:%s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str());
return false;
}
if (log) {
StreamString stream;
module_spec.Dump(stream);
- log->Printf("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
- __FUNCTION__, module_file_spec.GetPath().c_str(),
- arch.GetTriple().getTriple().c_str(), stream.GetData());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str(), stream.GetData());
}
m_cached_module_specs[key] = module_spec;
@@ -4361,6 +4283,10 @@ llvm::VersionTuple ProcessGDBRemote::GetHostOSVersion() {
return m_gdb_comm.GetOSVersion();
}
+llvm::VersionTuple ProcessGDBRemote::GetHostMacCatalystVersion() {
+ return m_gdb_comm.GetMacCatalystVersion();
+}
+
namespace {
typedef std::vector<std::string> stringVec;
@@ -4492,14 +4418,13 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
} else if (name == "invalidate_regnums") {
SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
} else if (name == "dynamic_size_dwarf_expr_bytes") {
- StringExtractor opcode_extractor;
std::string opcode_string = value.str();
size_t dwarf_opcode_len = opcode_string.length() / 2;
assert(dwarf_opcode_len > 0);
dwarf_opcode_bytes.resize(dwarf_opcode_len);
reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
- opcode_extractor.GetStringRef().swap(opcode_string);
+ StringExtractor opcode_extractor(opcode_string);
uint32_t ret_val =
opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
assert(dwarf_opcode_len == ret_val);
@@ -4565,16 +4490,15 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
// information to the current process. It will call itself recursively
// for nested register definition files. It returns true if it was able
// to fetch and parse an xml file.
-bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use,
- std::string xml_filename,
- uint32_t &cur_reg_num,
- uint32_t &reg_offset) {
+bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
+ ArchSpec &arch_to_use, std::string xml_filename, uint32_t &cur_reg_num,
+ uint32_t &reg_offset) {
// request the target xml file
std::string raw;
lldb_private::Status lldberr;
- if (!m_gdb_comm.ReadExtFeature(ConstString("features"),
- ConstString(xml_filename.c_str()),
- raw, lldberr)) {
+ if (!m_gdb_comm.ReadExtFeature(ConstString("features"),
+ ConstString(xml_filename.c_str()), raw,
+ lldberr)) {
return false;
}
@@ -4676,8 +4600,8 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_u
}
for (const auto &include : target_info.includes) {
- GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include,
- cur_reg_num, reg_offset);
+ GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, cur_reg_num,
+ reg_offset);
}
}
} else {
@@ -4705,41 +4629,43 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
return m_register_info.GetNumRegisters() > 0;
}
-Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
+llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {
// Make sure LLDB has an XML parser it can use first
if (!XMLDocument::XMLEnabled())
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "XML parsing not available");
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS);
- if (log)
- log->Printf("ProcessGDBRemote::%s", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s", __FUNCTION__);
+ LoadedModuleInfoList list;
GDBRemoteCommunicationClient &comm = m_gdb_comm;
bool can_use_svr4 = GetGlobalPluginProperties()->GetUseSVR4();
// check that we have extended feature read support
if (can_use_svr4 && comm.GetQXferLibrariesSVR4ReadSupported()) {
- list.clear();
-
// request the loaded library list
std::string raw;
lldb_private::Status lldberr;
if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""),
raw, lldberr))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error in libraries-svr4 packet");
// parse the xml file in memory
- if (log)
- log->Printf("parsing: %s", raw.c_str());
+ LLDB_LOGF(log, "parsing: %s", raw.c_str());
XMLDocument doc;
if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error reading noname.xml");
XMLNode root_element = doc.GetRootElement("library-list-svr4");
if (!root_element)
- return Status();
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Error finding library-list-svr4 xml element");
// main link map structure
llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
@@ -4791,10 +4717,11 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
module.get_base_is_offset(base_is_offset);
module.get_dynamic(ld);
- log->Printf("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64
- "[%s], ld:0x%08" PRIx64 ", name:'%s')",
- lm, base, (base_is_offset ? "offset" : "absolute"), ld,
- name.c_str());
+ LLDB_LOGF(log,
+ "found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64
+ "[%s], ld:0x%08" PRIx64 ", name:'%s')",
+ lm, base, (base_is_offset ? "offset" : "absolute"), ld,
+ name.c_str());
}
list.add(module);
@@ -4803,29 +4730,30 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
});
if (log)
- log->Printf("found %" PRId32 " modules in total",
- (int)list.m_list.size());
+ LLDB_LOGF(log, "found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ return list;
} else if (comm.GetQXferLibrariesReadSupported()) {
- list.clear();
-
// request the loaded library list
std::string raw;
lldb_private::Status lldberr;
if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw,
lldberr))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error in libraries packet");
- if (log)
- log->Printf("parsing: %s", raw.c_str());
+ LLDB_LOGF(log, "parsing: %s", raw.c_str());
XMLDocument doc;
if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error reading noname.xml");
XMLNode root_element = doc.GetRootElement("library-list");
if (!root_element)
- return Status();
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error finding library-list xml element");
root_element.ForEachChildElementWithName(
"library", [log, &list](const XMLNode &library) -> bool {
@@ -4853,8 +4781,8 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
module.get_base(base);
module.get_base_is_offset(base_is_offset);
- log->Printf("found (base:0x%08" PRIx64 "[%s], name:'%s')", base,
- (base_is_offset ? "offset" : "absolute"), name.c_str());
+ LLDB_LOGF(log, "found (base:0x%08" PRIx64 "[%s], name:'%s')", base,
+ (base_is_offset ? "offset" : "absolute"), name.c_str());
}
list.add(module);
@@ -4863,13 +4791,13 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
});
if (log)
- log->Printf("found %" PRId32 " modules in total",
- (int)list.m_list.size());
+ LLDB_LOGF(log, "found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ return list;
} else {
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Remote libraries not supported");
}
-
- return Status();
}
lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
@@ -4884,17 +4812,18 @@ lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
value_is_offset);
}
-size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
+llvm::Error ProcessGDBRemote::LoadModules() {
using lldb_private::process_gdb_remote::ProcessGDBRemote;
// request a list of loaded libraries from GDBServer
- if (GetLoadedModuleList(module_list).Fail())
- return 0;
+ llvm::Expected<LoadedModuleInfoList> module_list = GetLoadedModuleList();
+ if (!module_list)
+ return module_list.takeError();
// get a list of all the modules
ModuleList new_modules;
- for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list.m_list) {
+ for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list->m_list) {
std::string mod_name;
lldb::addr_t mod_base;
lldb::addr_t link_map;
@@ -4961,12 +4890,7 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
m_process->GetTarget().ModulesDidLoad(new_modules);
}
- return new_modules.GetSize();
-}
-
-size_t ProcessGDBRemote::LoadModules() {
- LoadedModuleInfoList module_list;
- return LoadModules(module_list);
+ return llvm::ErrorSuccess();
}
Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
@@ -5149,7 +5073,8 @@ ParseStructuredDataPacket(llvm::StringRef packet) {
if (!packet.consume_front(s_async_json_packet_prefix)) {
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"GDBRemoteCommunicationClientBase::%s() received $J packet "
"but was not a StructuredData packet: packet starts with "
"%s",
@@ -5164,16 +5089,18 @@ ParseStructuredDataPacket(llvm::StringRef packet) {
if (log) {
if (json_sp) {
StreamString json_str;
- json_sp->Dump(json_str);
+ json_sp->Dump(json_str, true);
json_str.Flush();
- log->Printf("ProcessGDBRemote::%s() "
- "received Async StructuredData packet: %s",
- __FUNCTION__, json_str.GetData());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s() "
+ "received Async StructuredData packet: %s",
+ __FUNCTION__, json_str.GetData());
} else {
- log->Printf("ProcessGDBRemote::%s"
- "() received StructuredData packet:"
- " parse failure",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s"
+ "() received StructuredData packet:"
+ " parse failure",
+ __FUNCTION__);
}
}
return json_sp;
@@ -5365,7 +5292,7 @@ public:
result.SetStatus(eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
output_strm.Printf(" packet: %s\n", packet_cstr);
- std::string &response_str = response.GetStringRef();
+ std::string response_str = response.GetStringRef();
if (strstr(packet_cstr, "qGetProfileData") != nullptr) {
response_str = process->HarmonizeThreadIdsForProfileData(response);
@@ -5374,7 +5301,7 @@ public:
if (response_str.empty())
output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
else
- output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
+ output_strm.Printf("response: %s\n", response.GetStringRef().data());
}
}
return true;
@@ -5423,7 +5350,7 @@ public:
if (response_str.empty())
output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
else
- output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
+ output_strm.Printf("response: %s\n", response.GetStringRef().data());
}
return true;
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 9c41fc2e5e98..0e3e3b39d9c8 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -24,8 +24,8 @@
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StringList.h"
@@ -199,10 +199,11 @@ public:
const llvm::Triple &triple) override;
llvm::VersionTuple GetHostOSVersion() override;
+ llvm::VersionTuple GetHostMacCatalystVersion() override;
- size_t LoadModules(LoadedModuleInfoList &module_list) override;
+ llvm::Error LoadModules() override;
- size_t LoadModules() override;
+ llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() override;
Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded,
lldb::addr_t &load_addr) override;
@@ -391,9 +392,6 @@ protected:
// Query remote GDBServer for register information
bool GetGDBServerRegisterInfo(ArchSpec &arch);
- // Query remote GDBServer for a detailed loaded library list
- Status GetLoadedModuleList(LoadedModuleInfoList &);
-
lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file,
lldb::addr_t link_map,
lldb::addr_t base_addr,
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
new file mode 100644
index 000000000000..16e7723e3061
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
@@ -0,0 +1,16 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "processgdbremote" in {
+ def PacketTimeout: Property<"packet-timeout", "UInt64">,
+ Global,
+ DefaultUnsignedValue<5>,
+ Desc<"Specify the default packet timeout in seconds.">;
+ def TargetDefinitionFile: Property<"target-definition-file", "FileSpec">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"The file that provides the description for remote target registers.">;
+ def UseSVR4: Property<"use-libraries-svr4", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules.">;
+}
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 6607bce4488b..8a6a58c55450 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -215,8 +215,7 @@ StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
StructuredData::ObjectSP object_sp;
const lldb::user_id_t tid = GetProtocolID();
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
- if (log)
- log->Printf("Fetching extended information for thread %4.4" PRIx64, tid);
+ LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid);
ProcessSP process_sp(GetProcess());
if (process_sp) {
ProcessGDBRemote *gdb_process =
@@ -230,9 +229,8 @@ void ThreadGDBRemote::WillResume(StateType resume_state) {
int signo = GetResumeSignal();
const lldb::user_id_t tid = GetProtocolID();
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
- if (log)
- log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
- StateAsCString(resume_state));
+ LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
+ StateAsCString(resume_state));
ProcessSP process_sp(GetProcess());
if (process_sp) {
diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp
index ff015aa54b76..70933f91fe51 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -188,6 +188,7 @@ ArchSpec MinidumpParser::GetArchitecture() {
case OSPlatform::Win32NT:
case OSPlatform::Win32CE:
triple.setOS(llvm::Triple::OSType::Win32);
+ triple.setVendor(llvm::Triple::VendorType::PC);
break;
case OSPlatform::Linux:
triple.setOS(llvm::Triple::OSType::Linux);
@@ -313,13 +314,15 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
return filtered_modules;
}
-const MinidumpExceptionStream *MinidumpParser::GetExceptionStream() {
- llvm::ArrayRef<uint8_t> data = GetStream(StreamType::Exception);
+const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() {
+ auto ExpectedStream = GetMinidumpFile().getExceptionStream();
+ if (ExpectedStream)
+ return &*ExpectedStream;
- if (data.size() == 0)
- return nullptr;
-
- return MinidumpExceptionStream::Parse(data);
+ LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS),
+ ExpectedStream.takeError(),
+ "Failed to read minidump exception stream: {0}");
+ return nullptr;
}
llvm::Optional<minidump::Range>
@@ -426,23 +429,35 @@ CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser,
static bool
CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser,
std::vector<MemoryRegionInfo> &regions) {
- auto data = parser.GetStream(StreamType::MemoryInfoList);
- if (data.empty())
- return false;
- auto mem_info_list = MinidumpMemoryInfo::ParseMemoryInfoList(data);
- if (mem_info_list.empty())
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES);
+ auto ExpectedInfo = parser.GetMinidumpFile().getMemoryInfoList();
+ if (!ExpectedInfo) {
+ LLDB_LOG_ERROR(log, ExpectedInfo.takeError(),
+ "Failed to read memory info list: {0}");
return false;
+ }
constexpr auto yes = MemoryRegionInfo::eYes;
constexpr auto no = MemoryRegionInfo::eNo;
- regions.reserve(mem_info_list.size());
- for (const auto &entry : mem_info_list) {
+ for (const MemoryInfo &entry : *ExpectedInfo) {
MemoryRegionInfo region;
- region.GetRange().SetRangeBase(entry->base_address);
- region.GetRange().SetByteSize(entry->region_size);
- region.SetReadable(entry->isReadable() ? yes : no);
- region.SetWritable(entry->isWritable() ? yes : no);
- region.SetExecutable(entry->isExecutable() ? yes : no);
- region.SetMapped(entry->isMapped() ? yes : no);
+ region.GetRange().SetRangeBase(entry.BaseAddress);
+ region.GetRange().SetByteSize(entry.RegionSize);
+
+ MemoryProtection prot = entry.Protect;
+ region.SetReadable(bool(prot & MemoryProtection::NoAccess) ? no : yes);
+ region.SetWritable(
+ bool(prot & (MemoryProtection::ReadWrite | MemoryProtection::WriteCopy |
+ MemoryProtection::ExecuteReadWrite |
+ MemoryProtection::ExeciteWriteCopy))
+ ? yes
+ : no);
+ region.SetExecutable(
+ bool(prot & (MemoryProtection::Execute | MemoryProtection::ExecuteRead |
+ MemoryProtection::ExecuteReadWrite |
+ MemoryProtection::ExeciteWriteCopy))
+ ? yes
+ : no);
+ region.SetMapped(entry.State != MemoryState::Free ? yes : no);
regions.push_back(region);
}
return !regions.empty();
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
index fce64f0ed5fc..d206fe6c9a00 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -82,7 +82,7 @@ public:
// have the same name, it keeps the copy with the lowest load address.
std::vector<const minidump::Module *> GetFilteredModuleList();
- const MinidumpExceptionStream *GetExceptionStream();
+ const llvm::minidump::ExceptionStream *GetExceptionStream();
llvm::Optional<Range> FindMemoryRange(lldb::addr_t addr);
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp
index d7fc6e43d090..ed00b1cc07db 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.cpp
+++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -57,17 +57,6 @@ LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) {
lldb::pid_t LinuxProcStatus::GetPid() const { return pid; }
-// Exception stuff
-const MinidumpExceptionStream *
-MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) {
- const MinidumpExceptionStream *exception_stream = nullptr;
- Status error = consumeObject(data, exception_stream);
- if (error.Fail())
- return nullptr;
-
- return exception_stream;
-}
-
std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) {
const llvm::support::ulittle64_t *mem_ranges_count;
@@ -87,29 +76,3 @@ MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) {
*mem_ranges_count),
*base_rva);
}
-
-std::vector<const MinidumpMemoryInfo *>
-MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) {
- const MinidumpMemoryInfoListHeader *header;
- Status error = consumeObject(data, header);
- if (error.Fail() ||
- header->size_of_header < sizeof(MinidumpMemoryInfoListHeader) ||
- header->size_of_entry < sizeof(MinidumpMemoryInfo))
- return {};
-
- data = data.drop_front(header->size_of_header -
- sizeof(MinidumpMemoryInfoListHeader));
-
- if (header->size_of_entry * header->num_of_entries > data.size())
- return {};
-
- std::vector<const MinidumpMemoryInfo *> result;
- result.reserve(header->num_of_entries);
-
- for (uint64_t i = 0; i < header->num_of_entries; ++i) {
- result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>(
- data.data() + i * header->size_of_entry));
- }
-
- return result;
-}
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h
index b4878e82de5d..a9c807930ebf 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.h
+++ b/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -85,90 +85,6 @@ struct MinidumpMemoryDescriptor64 {
static_assert(sizeof(MinidumpMemoryDescriptor64) == 16,
"sizeof MinidumpMemoryDescriptor64 is not correct!");
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680385(v=vs.85).aspx
-struct MinidumpMemoryInfoListHeader {
- llvm::support::ulittle32_t size_of_header;
- llvm::support::ulittle32_t size_of_entry;
- llvm::support::ulittle64_t num_of_entries;
-};
-static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16,
- "sizeof MinidumpMemoryInfoListHeader is not correct!");
-
-enum class MinidumpMemoryInfoState : uint32_t {
- MemCommit = 0x1000,
- MemFree = 0x10000,
- MemReserve = 0x2000,
- LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree)
-};
-
-enum class MinidumpMemoryInfoType : uint32_t {
- MemImage = 0x1000000,
- MemMapped = 0x40000,
- MemPrivate = 0x20000,
- LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage)
-};
-
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
-enum class MinidumpMemoryProtectionContants : uint32_t {
- PageExecute = 0x10,
- PageExecuteRead = 0x20,
- PageExecuteReadWrite = 0x40,
- PageExecuteWriteCopy = 0x80,
- PageNoAccess = 0x01,
- PageReadOnly = 0x02,
- PageReadWrite = 0x04,
- PageWriteCopy = 0x08,
- PageTargetsInvalid = 0x40000000,
- PageTargetsNoUpdate = 0x40000000,
-
- PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite |
- PageWriteCopy,
- PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite |
- PageExecuteWriteCopy,
- LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid)
-};
-
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx
-struct MinidumpMemoryInfo {
- llvm::support::ulittle64_t base_address;
- llvm::support::ulittle64_t allocation_base;
- llvm::support::ulittle32_t allocation_protect;
- llvm::support::ulittle32_t alignment1;
- llvm::support::ulittle64_t region_size;
- llvm::support::ulittle32_t state;
- llvm::support::ulittle32_t protect;
- llvm::support::ulittle32_t type;
- llvm::support::ulittle32_t alignment2;
-
- static std::vector<const MinidumpMemoryInfo *>
- ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
-
- bool isReadable() const {
- const auto mask = MinidumpMemoryProtectionContants::PageNoAccess;
- return (static_cast<uint32_t>(mask) & protect) == 0;
- }
-
- bool isWritable() const {
- const auto mask = MinidumpMemoryProtectionContants::PageWritable;
- return (static_cast<uint32_t>(mask) & protect) != 0;
- }
-
- bool isExecutable() const {
- const auto mask = MinidumpMemoryProtectionContants::PageExecutable;
- return (static_cast<uint32_t>(mask) & protect) != 0;
- }
-
- bool isMapped() const {
- return state != static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree);
- }
-};
-
-static_assert(sizeof(MinidumpMemoryInfo) == 48,
- "sizeof MinidumpMemoryInfo is not correct!");
-
// TODO misc2, misc3 ?
// Reference:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx
@@ -202,35 +118,6 @@ private:
LinuxProcStatus() = default;
};
-// Exception stuff
-struct MinidumpException {
- enum : unsigned {
- ExceptonInfoMaxParams = 15,
- DumpRequested = 0xFFFFFFFF,
- };
-
- llvm::support::ulittle32_t exception_code;
- llvm::support::ulittle32_t exception_flags;
- llvm::support::ulittle64_t exception_record;
- llvm::support::ulittle64_t exception_address;
- llvm::support::ulittle32_t number_parameters;
- llvm::support::ulittle32_t unused_alignment;
- llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams];
-};
-static_assert(sizeof(MinidumpException) == 152,
- "sizeof MinidumpException is not correct!");
-
-struct MinidumpExceptionStream {
- llvm::support::ulittle32_t thread_id;
- llvm::support::ulittle32_t alignment;
- MinidumpException exception_record;
- LocationDescriptor thread_context;
-
- static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data);
-};
-static_assert(sizeof(MinidumpExceptionStream) == 168,
- "sizeof MinidumpExceptionStream is not correct!");
-
} // namespace minidump
} // namespace lldb_private
#endif // liblldb_MinidumpTypes_h_
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp
index a7fc42cad16c..e30a3c82a887 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -49,16 +49,19 @@ namespace {
class PlaceholderObjectFile : public ObjectFile {
public:
PlaceholderObjectFile(const lldb::ModuleSP &module_sp,
- const ModuleSpec &module_spec, lldb::offset_t base,
- lldb::offset_t size)
+ const ModuleSpec &module_spec, lldb::addr_t base,
+ lldb::addr_t size)
: ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0,
/*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0),
m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()),
m_base(base), m_size(size) {
- m_symtab_up = llvm::make_unique<Symtab>(this);
+ m_symtab_up = std::make_unique<Symtab>(this);
}
- ConstString GetPluginName() override { return ConstString("placeholder"); }
+ static ConstString GetStaticPluginName() {
+ return ConstString("placeholder");
+ }
+ ConstString GetPluginName() override { return GetStaticPluginName(); }
uint32_t GetPluginVersion() override { return 1; }
bool ParseHeader() override { return true; }
Type CalculateType() override { return eTypeUnknown; }
@@ -80,7 +83,7 @@ public:
}
void CreateSections(SectionList &unified_section_list) override {
- m_sections_up = llvm::make_unique<SectionList>();
+ m_sections_up = std::make_unique<SectionList>();
auto section_sp = std::make_shared<Section>(
GetModule(), this, /*sect_id*/ 0, ConstString(".module_image"),
eSectionTypeOther, m_base, m_size, /*file_offset*/ 0, /*file_size*/ 0,
@@ -109,11 +112,12 @@ public:
GetFileSpec(), m_base, m_base + m_size);
}
+ lldb::addr_t GetBaseImageAddress() const { return m_base; }
private:
ArchSpec m_arch;
UUID m_uuid;
- lldb::offset_t m_base;
- lldb::offset_t m_size;
+ lldb::addr_t m_base;
+ lldb::addr_t m_size;
};
} // namespace
@@ -215,6 +219,9 @@ Status ProcessMinidump::DoLoadCore() {
m_thread_list = m_minidump_parser->GetThreads();
m_active_exception = m_minidump_parser->GetExceptionStream();
+
+ SetUnixSignals(UnixSignals::Create(GetArchitecture()));
+
ReadModuleList();
llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid();
@@ -234,39 +241,56 @@ uint32_t ProcessMinidump::GetPluginVersion() { return 1; }
Status ProcessMinidump::DoDestroy() { return Status(); }
void ProcessMinidump::RefreshStateAfterStop() {
+
if (!m_active_exception)
return;
- if (m_active_exception->exception_record.exception_code ==
- MinidumpException::DumpRequested) {
+ constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF;
+ if (m_active_exception->ExceptionRecord.ExceptionCode ==
+ BreakpadDumpRequested) {
+ // This "ExceptionCode" value is a sentinel that is sometimes used
+ // when generating a dump for a process that hasn't crashed.
+
+ // TODO: The definition and use of this "dump requested" constant
+ // in Breakpad are actually Linux-specific, and for similar use
+ // cases on Mac/Windows it defines differnt constants, referring
+ // to them as "simulated" exceptions; consider moving this check
+ // down to the OS-specific paths and checking each OS for its own
+ // constant.
return;
}
lldb::StopInfoSP stop_info;
lldb::ThreadSP stop_thread;
- Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id);
+ Process::m_thread_list.SetSelectedThreadByID(m_active_exception->ThreadId);
stop_thread = Process::m_thread_list.GetSelectedThread();
ArchSpec arch = GetArchitecture();
if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
+ uint32_t signo = m_active_exception->ExceptionRecord.ExceptionCode;
+
+ if (signo == 0) {
+ // No stop.
+ return;
+ }
+
stop_info = StopInfo::CreateStopReasonWithSignal(
- *stop_thread, m_active_exception->exception_record.exception_code);
+ *stop_thread, signo);
} else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) {
stop_info = StopInfoMachException::CreateStopReasonWithMachException(
- *stop_thread, m_active_exception->exception_record.exception_code, 2,
- m_active_exception->exception_record.exception_flags,
- m_active_exception->exception_record.exception_address, 0);
+ *stop_thread, m_active_exception->ExceptionRecord.ExceptionCode, 2,
+ m_active_exception->ExceptionRecord.ExceptionFlags,
+ m_active_exception->ExceptionRecord.ExceptionAddress, 0);
} else {
std::string desc;
llvm::raw_string_ostream desc_stream(desc);
desc_stream << "Exception "
<< llvm::format_hex(
- m_active_exception->exception_record.exception_code, 8)
+ m_active_exception->ExceptionRecord.ExceptionCode, 8)
<< " encountered at address "
<< llvm::format_hex(
- m_active_exception->exception_record.exception_address,
- 8);
+ m_active_exception->ExceptionRecord.ExceptionAddress, 8);
stop_info = StopInfo::CreateStopReasonWithException(
*stop_thread, desc_stream.str().c_str());
}
@@ -331,8 +355,8 @@ bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list,
// If the minidump contains an exception context, use it
if (m_active_exception != nullptr &&
- m_active_exception->thread_id == thread.ThreadId) {
- context_location = m_active_exception->thread_context;
+ m_active_exception->ThreadId == thread.ThreadId) {
+ context_location = m_active_exception->ThreadContext;
}
llvm::ArrayRef<uint8_t> context;
@@ -351,14 +375,15 @@ void ProcessMinidump::ReadModuleList() {
std::vector<const minidump::Module *> filtered_modules =
m_minidump_parser->GetFilteredModuleList();
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
for (auto module : filtered_modules) {
std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString(
module->ModuleNameRVA));
+ const uint64_t load_addr = module->BaseOfImage;
+ const uint64_t load_size = module->SizeOfImage;
LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name,
- module->BaseOfImage, module->BaseOfImage + module->SizeOfImage,
- module->SizeOfImage);
+ load_addr, load_addr + load_size, load_size);
// check if the process is wow64 - a 32 bit windows process running on a
// 64 bit windows
@@ -373,7 +398,7 @@ void ProcessMinidump::ReadModuleList() {
Status error;
// Try and find a module with a full UUID that matches. This function will
// add the module to the target if it finds one.
- lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec,
+ lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec,
true /* notify */, &error);
if (!module_sp) {
// Try and find a module without specifying the UUID and only looking for
@@ -386,8 +411,8 @@ void ProcessMinidump::ReadModuleList() {
ModuleSpec basename_module_spec(module_spec);
basename_module_spec.GetUUID().Clear();
basename_module_spec.GetFileSpec().GetDirectory().Clear();
- module_sp = GetTarget().GetOrCreateModule(basename_module_spec,
- true /* notify */, &error);
+ module_sp = GetTarget().GetOrCreateModule(basename_module_spec,
+ true /* notify */, &error);
if (module_sp) {
// We consider the module to be a match if the minidump UUID is a
// prefix of the actual UUID, or if either of the UUIDs are empty.
@@ -401,6 +426,19 @@ void ProcessMinidump::ReadModuleList() {
}
}
}
+ if (module_sp) {
+ // Watch out for place holder modules that have different paths, but the
+ // same UUID. If the base address is different, create a new module. If
+ // we don't then we will end up setting the load address of a different
+ // PlaceholderObjectFile and an assertion will fire.
+ auto *objfile = module_sp->GetObjectFile();
+ if (objfile && objfile->GetPluginName() ==
+ PlaceholderObjectFile::GetStaticPluginName()) {
+ if (((PlaceholderObjectFile *)objfile)->GetBaseImageAddress() !=
+ load_addr)
+ module_sp.reset();
+ }
+ }
if (!module_sp) {
// We failed to locate a matching local object file. Fortunately, the
// minidump format encodes enough information about each module's memory
@@ -415,12 +453,12 @@ void ProcessMinidump::ReadModuleList() {
name);
module_sp = Module::CreateModuleFromObjectFile<PlaceholderObjectFile>(
- module_spec, module->BaseOfImage, module->SizeOfImage);
+ module_spec, load_addr, load_size);
GetTarget().GetImages().Append(module_sp, true /* notify */);
}
bool load_addr_changed = false;
- module_sp->SetLoadAddress(GetTarget(), module->BaseOfImage, false,
+ module_sp->SetLoadAddress(GetTarget(), load_addr, false,
load_addr_changed);
}
}
@@ -444,7 +482,7 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) {
// debug information than needed.
JITLoaderList &ProcessMinidump::GetJITLoaders() {
if (!m_jit_loaders_up) {
- m_jit_loaders_up = llvm::make_unique<JITLoaderList>();
+ m_jit_loaders_up = std::make_unique<JITLoaderList>();
}
return *m_jit_loaders_up;
}
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
index c39040f61dc5..22dc24af7c0e 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -108,7 +108,7 @@ private:
FileSpec m_core_file;
lldb::DataBufferSP m_core_data;
llvm::ArrayRef<minidump::Thread> m_thread_list;
- const MinidumpExceptionStream *m_active_exception;
+ const minidump::ExceptionStream *m_active_exception;
lldb::CommandObjectSP m_command_sp;
bool m_is_wow64;
};
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
index f2e456097dfc..72dead07dcb4 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
@@ -9,6 +9,7 @@
#include "RegisterContextMinidump_ARM.h"
#include "Utility/ARM_DWARF_Registers.h"
+#include "Utility/ARM_ehframe_Registers.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -29,14 +30,14 @@ using namespace minidump;
#define DEF_R(i) \
{ \
"r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
- {dwarf_r##i, dwarf_r##i, INV, INV, reg_r##i}, \
+ {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, \
nullptr, nullptr, nullptr, 0 \
}
#define DEF_R_ARG(i, n) \
{ \
"r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
- {dwarf_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \
+ {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \
nullptr, nullptr, nullptr, 0 \
}
@@ -173,7 +174,7 @@ static RegisterInfo g_reg_info_apple_fp = {
OFFSET(r) + 7 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},
+ {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},
nullptr,
nullptr,
nullptr,
@@ -186,7 +187,7 @@ static RegisterInfo g_reg_info_fp = {
OFFSET(r) + 11 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},
+ {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},
nullptr,
nullptr,
nullptr,
@@ -213,7 +214,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(r) + 13 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
nullptr,
nullptr,
nullptr,
@@ -224,7 +225,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(r) + 14 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
nullptr,
nullptr,
nullptr,
@@ -235,7 +236,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(r) + 15 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
nullptr,
nullptr,
nullptr,
@@ -246,7 +247,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(cpsr),
eEncodingUint,
eFormatHex,
- {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
nullptr,
nullptr,
nullptr,
@@ -476,12 +477,22 @@ RegisterContextMinidump_ARM::RegisterContextMinidump_ARM(
lldbassert(k_num_regs == k_num_reg_infos);
}
-size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; }
+size_t RegisterContextMinidump_ARM::GetRegisterCountStatic() {
+ return k_num_regs;
+}
+
+// Used for unit testing so we can verify register info is filled in for
+// all register flavors (DWARF, EH Frame, generic, etc).
+size_t RegisterContextMinidump_ARM::GetRegisterCount() {
+ return GetRegisterCountStatic();
+}
+// Used for unit testing so we can verify register info is filled in.
const RegisterInfo *
-RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
+RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(size_t reg,
+ bool apple) {
if (reg < k_num_reg_infos) {
- if (m_apple) {
+ if (apple) {
if (reg == reg_r7)
return &g_reg_info_apple_fp;
} else {
@@ -493,6 +504,11 @@ RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
return nullptr;
}
+const RegisterInfo *
+RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
+ return GetRegisterInfoAtIndexStatic(reg, m_apple);
+}
+
size_t RegisterContextMinidump_ARM::GetRegisterSetCount() {
return k_num_reg_sets;
}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
index eff8cdfef00a..7af3b98a6fe7 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
@@ -38,6 +38,12 @@ public:
// Do nothing... registers are always valid...
}
+ // Used for unit testing.
+ static size_t GetRegisterCountStatic();
+ // Used for unit testing.
+ static const lldb_private::RegisterInfo *
+ GetRegisterInfoAtIndexStatic(size_t reg, bool apple);
+
size_t GetRegisterCount() override;
const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
diff --git a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index 7b9598379553..3517f831970d 100644
--- a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -28,13 +28,13 @@ ScriptInterpreterNone::~ScriptInterpreterNone() {}
bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command,
CommandReturnObject *,
const ExecuteScriptOptions &) {
- m_debugger.GetErrorFile()->PutCString(
+ m_debugger.GetErrorStream().PutCString(
"error: there is no embedded script interpreter in this mode.\n");
return false;
}
void ScriptInterpreterNone::ExecuteInterpreterLoop() {
- m_debugger.GetErrorFile()->PutCString(
+ m_debugger.GetErrorStream().PutCString(
"error: there is no embedded script interpreter in this mode.\n");
}
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 29dd037efd86..70d93424fdec 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -18,9 +18,11 @@
#include "lldb/Host/File.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Errno.h"
@@ -28,9 +30,41 @@
using namespace lldb_private;
using namespace lldb;
+using namespace lldb_private::python;
+using llvm::cantFail;
+using llvm::Error;
+using llvm::Expected;
+using llvm::Twine;
-void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const {
- s << "Python Obj: 0x" << GetValue();
+template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ return obj.get().IsTrue();
+}
+
+template <>
+Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ return obj.get().AsLongLong();
+}
+
+template <>
+Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ PyObject *str_obj = PyObject_Str(obj.get().get());
+ if (!obj)
+ return llvm::make_error<PythonException>();
+ auto str = Take<PythonString>(str_obj);
+ auto utf8 = str.AsUTF8();
+ if (!utf8)
+ return utf8.takeError();
+ return utf8.get();
+}
+
+void StructuredPythonObject::Serialize(llvm::json::OStream &s) const {
+ s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str());
}
// PythonObject
@@ -167,12 +201,6 @@ PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
PyObject_GetAttr(m_py_obj, py_attr.get()));
}
-bool PythonObject::IsNone() const { return m_py_obj == Py_None; }
-
-bool PythonObject::IsValid() const { return m_py_obj != nullptr; }
-
-bool PythonObject::IsAllocated() const { return IsValid() && !IsNone(); }
-
StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
switch (GetObjectType()) {
case PyObjectType::Dictionary:
@@ -201,43 +229,19 @@ StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
}
// PythonString
-PythonBytes::PythonBytes() : PythonObject() {}
-PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() {
- SetBytes(bytes);
-}
+PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
-PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() {
+PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) {
SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
}
-PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
-}
-
-PythonBytes::~PythonBytes() {}
-
bool PythonBytes::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyBytes_Check(py_obj);
}
-void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonBytes::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
if (!IsValid())
return llvm::ArrayRef<uint8_t>();
@@ -257,8 +261,7 @@ size_t PythonBytes::GetSize() const {
void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
const char *data = reinterpret_cast<const char *>(bytes.data());
- PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
- PythonObject::Reset(PyRefType::Owned, py_bytes);
+ *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
}
StructuredData::StringSP PythonBytes::CreateStructuredString() const {
@@ -275,39 +278,15 @@ PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
const char *str = reinterpret_cast<const char *>(bytes);
- Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
-}
-
-PythonByteArray::PythonByteArray(PyRefType type, PyObject *o) {
- Reset(type, o);
+ *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
}
-PythonByteArray::PythonByteArray(const PythonBytes &object)
- : PythonObject(object) {}
-
-PythonByteArray::~PythonByteArray() {}
-
bool PythonByteArray::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyByteArray_Check(py_obj);
}
-void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonByteArray::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
if (!IsValid())
return llvm::ArrayRef<uint8_t>();
@@ -334,21 +313,18 @@ StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
// PythonString
-PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
-}
-
-PythonString::PythonString(llvm::StringRef string) : PythonObject() {
- SetString(string);
-}
-
-PythonString::PythonString(const char *string) : PythonObject() {
- SetString(llvm::StringRef(string));
+Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) {
+#if PY_MAJOR_VERSION >= 3
+ PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size());
+#else
+ PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
+#endif
+ if (!str)
+ return llvm::make_error<PythonException>();
+ return Take<PythonString>(str);
}
-PythonString::PythonString() : PythonObject() {}
-
-PythonString::~PythonString() {}
+PythonString::PythonString(llvm::StringRef string) { SetString(string); }
bool PythonString::Check(PyObject *py_obj) {
if (!py_obj)
@@ -363,30 +339,40 @@ bool PythonString::Check(PyObject *py_obj) {
return false;
}
-void PythonString::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonString::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
+void PythonString::Convert(PyRefType &type, PyObject *&py_obj) {
#if PY_MAJOR_VERSION < 3
// In Python 2, Don't store PyUnicode objects directly, because we need
// access to their underlying character buffers which Python 2 doesn't
// provide.
- if (PyUnicode_Check(py_obj))
- result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
+ if (PyUnicode_Check(py_obj)) {
+ PyObject *s = PyUnicode_AsUTF8String(py_obj);
+ if (s == nullptr) {
+ PyErr_Clear();
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ return;
+ }
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ else
+ type = PyRefType::Owned;
+ py_obj = s;
+ }
#endif
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
}
llvm::StringRef PythonString::GetString() const {
+ auto s = AsUTF8();
+ if (!s) {
+ llvm::consumeError(s.takeError());
+ return llvm::StringRef("");
+ }
+ return s.get();
+}
+
+Expected<llvm::StringRef> PythonString::AsUTF8() const {
if (!IsValid())
- return llvm::StringRef();
+ return nullDeref();
Py_ssize_t size;
const char *data;
@@ -394,10 +380,16 @@ llvm::StringRef PythonString::GetString() const {
#if PY_MAJOR_VERSION >= 3
data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
#else
- char *c;
- PyString_AsStringAndSize(m_py_obj, &c, &size);
+ char *c = NULL;
+ int r = PyString_AsStringAndSize(m_py_obj, &c, &size);
+ if (r < 0)
+ c = NULL;
data = c;
#endif
+
+ if (!data)
+ return exception();
+
return llvm::StringRef(data, size);
}
@@ -413,13 +405,13 @@ size_t PythonString::GetSize() const {
}
void PythonString::SetString(llvm::StringRef string) {
-#if PY_MAJOR_VERSION >= 3
- PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
- PythonObject::Reset(PyRefType::Owned, unicode);
-#else
- PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
- PythonObject::Reset(PyRefType::Owned, str);
-#endif
+ auto s = FromUTF8(string);
+ if (!s) {
+ llvm::consumeError(s.takeError());
+ Reset();
+ } else {
+ *this = std::move(s.get());
+ }
}
StructuredData::StringSP PythonString::CreateStructuredString() const {
@@ -430,18 +422,7 @@ StructuredData::StringSP PythonString::CreateStructuredString() const {
// PythonInteger
-PythonInteger::PythonInteger() : PythonObject() {}
-
-PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
- : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
-}
-
-PythonInteger::PythonInteger(int64_t value) : PythonObject() {
- SetInteger(value);
-}
-
-PythonInteger::~PythonInteger() {}
+PythonInteger::PythonInteger(int64_t value) { SetInteger(value); }
bool PythonInteger::Check(PyObject *py_obj) {
if (!py_obj)
@@ -456,16 +437,7 @@ bool PythonInteger::Check(PyObject *py_obj) {
#endif
}
-void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonInteger::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
+void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) {
#if PY_MAJOR_VERSION < 3
// Always store this as a PyLong, which makes interoperability between Python
// 2.x and Python 3.x easier. This is only necessary in 2.x, since 3.x
@@ -474,16 +446,23 @@ void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
// Since we converted the original object to a different type, the new
// object is an owned object regardless of the ownership semantics
// requested by the user.
- result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
+ long long value = PyInt_AsLong(py_obj);
+ PyObject *l = nullptr;
+ if (!PyErr_Occurred())
+ l = PyLong_FromLongLong(value);
+ if (l == nullptr) {
+ PyErr_Clear();
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ return;
+ }
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ else
+ type = PyRefType::Owned;
+ py_obj = l;
}
#endif
-
- assert(PyLong_Check(result.get()) &&
- "Couldn't get a PyLong from this PyObject");
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
}
int64_t PythonInteger::GetInteger() const {
@@ -506,7 +485,7 @@ int64_t PythonInteger::GetInteger() const {
}
void PythonInteger::SetInteger(int64_t value) {
- PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
+ *this = Take<PythonInteger>(PyLong_FromLongLong(value));
}
StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
@@ -517,11 +496,6 @@ StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
// PythonBoolean
-PythonBoolean::PythonBoolean(PyRefType type, PyObject *py_obj)
- : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a boolean type
-}
-
PythonBoolean::PythonBoolean(bool value) {
SetValue(value);
}
@@ -530,27 +504,12 @@ bool PythonBoolean::Check(PyObject *py_obj) {
return py_obj ? PyBool_Check(py_obj) : false;
}
-void PythonBoolean::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonBoolean::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
bool PythonBoolean::GetValue() const {
return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
}
void PythonBoolean::SetValue(bool value) {
- PythonObject::Reset(PyRefType::Owned, PyBool_FromLong(value));
+ *this = Take<PythonBoolean>(PyBool_FromLong(value));
}
StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
@@ -561,42 +520,21 @@ StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
// PythonList
-PythonList::PythonList(PyInitialValue value) : PythonObject() {
+PythonList::PythonList(PyInitialValue value) {
if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyList_New(0));
-}
-
-PythonList::PythonList(int list_size) : PythonObject() {
- Reset(PyRefType::Owned, PyList_New(list_size));
+ *this = Take<PythonList>(PyList_New(0));
}
-PythonList::PythonList(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
+PythonList::PythonList(int list_size) {
+ *this = Take<PythonList>(PyList_New(list_size));
}
-PythonList::~PythonList() {}
-
bool PythonList::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyList_Check(py_obj);
}
-void PythonList::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonList::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
uint32_t PythonList::GetSize() const {
if (IsValid())
return PyList_GET_SIZE(m_py_obj);
@@ -638,17 +576,13 @@ StructuredData::ArraySP PythonList::CreateStructuredArray() const {
// PythonTuple
-PythonTuple::PythonTuple(PyInitialValue value) : PythonObject() {
+PythonTuple::PythonTuple(PyInitialValue value) {
if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyTuple_New(0));
-}
-
-PythonTuple::PythonTuple(int tuple_size) : PythonObject() {
- Reset(PyRefType::Owned, PyTuple_New(tuple_size));
+ *this = Take<PythonTuple>(PyTuple_New(0));
}
-PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
+PythonTuple::PythonTuple(int tuple_size) {
+ *this = Take<PythonTuple>(PyTuple_New(tuple_size));
}
PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
@@ -674,29 +608,12 @@ PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
}
}
-PythonTuple::~PythonTuple() {}
-
bool PythonTuple::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyTuple_Check(py_obj);
}
-void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonTuple::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
uint32_t PythonTuple::GetSize() const {
if (IsValid())
return PyTuple_GET_SIZE(m_py_obj);
@@ -730,18 +647,11 @@ StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
// PythonDictionary
-PythonDictionary::PythonDictionary(PyInitialValue value) : PythonObject() {
+PythonDictionary::PythonDictionary(PyInitialValue value) {
if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyDict_New());
+ *this = Take<PythonDictionary>(PyDict_New());
}
-PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj)
- : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
-}
-
-PythonDictionary::~PythonDictionary() {}
-
bool PythonDictionary::Check(PyObject *py_obj) {
if (!py_obj)
return false;
@@ -749,21 +659,6 @@ bool PythonDictionary::Check(PyObject *py_obj) {
return PyDict_Check(py_obj);
}
-void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonDictionary::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
uint32_t PythonDictionary::GetSize() const {
if (IsValid())
return PyDict_Size(m_py_obj);
@@ -777,16 +672,66 @@ PythonList PythonDictionary::GetKeys() const {
}
PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
- if (IsAllocated() && key.IsValid())
- return PythonObject(PyRefType::Borrowed,
- PyDict_GetItem(m_py_obj, key.get()));
- return PythonObject();
+ auto item = GetItem(key);
+ if (!item) {
+ llvm::consumeError(item.takeError());
+ return PythonObject();
+ }
+ return std::move(item.get());
+}
+
+Expected<PythonObject>
+PythonDictionary::GetItem(const PythonObject &key) const {
+ if (!IsValid())
+ return nullDeref();
+#if PY_MAJOR_VERSION >= 3
+ PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
+ if (PyErr_Occurred())
+ return exception();
+#else
+ PyObject *o = PyDict_GetItem(m_py_obj, key.get());
+#endif
+ if (!o)
+ return keyError();
+ return Retain<PythonObject>(o);
+}
+
+Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const {
+ if (!IsValid())
+ return nullDeref();
+ PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
+ if (PyErr_Occurred())
+ return exception();
+ if (!o)
+ return keyError();
+ return Retain<PythonObject>(o);
+}
+
+Error PythonDictionary::SetItem(const PythonObject &key,
+ const PythonObject &value) const {
+ if (!IsValid() || !value.IsValid())
+ return nullDeref();
+ int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
+ if (r < 0)
+ return exception();
+ return Error::success();
+}
+
+Error PythonDictionary::SetItem(const Twine &key,
+ const PythonObject &value) const {
+ if (!IsValid() || !value.IsValid())
+ return nullDeref();
+ int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
+ if (r < 0)
+ return exception();
+ return Error::success();
}
void PythonDictionary::SetItemForKey(const PythonObject &key,
const PythonObject &value) {
- if (IsAllocated() && key.IsValid() && value.IsValid())
- PyDict_SetItem(m_py_obj, key.get(), value.get());
+ Error error = SetItem(key, value);
+ if (error)
+ llvm::consumeError(std::move(error));
}
StructuredData::DictionarySP
@@ -803,14 +748,6 @@ PythonDictionary::CreateStructuredDictionary() const {
return result;
}
-PythonModule::PythonModule() : PythonObject() {}
-
-PythonModule::PythonModule(PyRefType type, PyObject *py_obj) {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
-}
-
-PythonModule::~PythonModule() {}
-
PythonModule PythonModule::BuiltinsModule() {
#if PY_MAJOR_VERSION >= 3
return AddModule("builtins");
@@ -826,9 +763,23 @@ PythonModule PythonModule::AddModule(llvm::StringRef module) {
return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
}
-PythonModule PythonModule::ImportModule(llvm::StringRef module) {
- std::string str = module.str();
- return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
+Expected<PythonModule> PythonModule::Import(const Twine &name) {
+ PyObject *mod = PyImport_ImportModule(NullTerminated(name));
+ if (!mod)
+ return exception();
+ return Take<PythonModule>(mod);
+}
+
+Expected<PythonObject> PythonModule::Get(const Twine &name) {
+ if (!IsValid())
+ return nullDeref();
+ PyObject *dict = PyModule_GetDict(m_py_obj);
+ if (!dict)
+ return exception();
+ PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
+ if (!item)
+ return exception();
+ return Retain<PythonObject>(item);
}
bool PythonModule::Check(PyObject *py_obj) {
@@ -838,33 +789,12 @@ bool PythonModule::Check(PyObject *py_obj) {
return PyModule_Check(py_obj);
}
-void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonModule::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
PythonDictionary PythonModule::GetDictionary() const {
- return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
-}
-
-PythonCallable::PythonCallable() : PythonObject() {}
-
-PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj) {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
+ if (!IsValid())
+ return PythonDictionary();
+ return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
}
-PythonCallable::~PythonCallable() {}
-
bool PythonCallable::Check(PyObject *py_obj) {
if (!py_obj)
return false;
@@ -872,32 +802,80 @@ bool PythonCallable::Check(PyObject *py_obj) {
return PyCallable_Check(py_obj);
}
-void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonCallable::Check(py_obj)) {
- PythonObject::Reset();
- return;
+PythonCallable::ArgInfo PythonCallable::GetNumInitArguments() const {
+ auto arginfo = GetInitArgInfo();
+ if (!arginfo) {
+ llvm::consumeError(arginfo.takeError());
+ return ArgInfo{};
}
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ return arginfo.get();
}
-PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
- ArgInfo result = {0, false, false, false};
+Expected<PythonCallable::ArgInfo> PythonCallable::GetInitArgInfo() const {
if (!IsValid())
- return result;
+ return nullDeref();
+ auto init = As<PythonCallable>(GetAttribute("__init__"));
+ if (!init)
+ return init.takeError();
+ return init.get().GetArgInfo();
+}
+
+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
+static const char get_arg_info_script[] = R"(
+from inspect import signature, Parameter, ismethod
+from collections import namedtuple
+ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs', 'is_bound_method'])
+def main(f):
+ count = 0
+ varargs = False
+ for parameter in signature(f).parameters.values():
+ kind = parameter.kind
+ if kind in (Parameter.POSITIONAL_ONLY,
+ Parameter.POSITIONAL_OR_KEYWORD):
+ count += 1
+ elif kind == Parameter.VAR_POSITIONAL:
+ varargs = True
+ elif kind in (Parameter.KEYWORD_ONLY,
+ Parameter.VAR_KEYWORD):
+ pass
+ else:
+ raise Exception(f'unknown parameter kind: {kind}')
+ return ArgInfo(count, varargs, ismethod(f))
+)";
+#endif
+
+Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
+ ArgInfo result = {};
+ if (!IsValid())
+ return nullDeref();
+
+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
+
+ // no need to synchronize access to this global, we already have the GIL
+ static PythonScript get_arg_info(get_arg_info_script);
+ Expected<PythonObject> pyarginfo = get_arg_info(*this);
+ if (!pyarginfo)
+ return pyarginfo.takeError();
+ result.count = cantFail(As<long long>(pyarginfo.get().GetAttribute("count")));
+ result.has_varargs =
+ cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs")));
+ bool is_method =
+ cantFail(As<bool>(pyarginfo.get().GetAttribute("is_bound_method")));
+ result.max_positional_args =
+ result.has_varargs ? ArgInfo::UNBOUNDED : result.count;
+
+ // FIXME emulate old broken behavior
+ if (is_method)
+ result.count++;
+#else
+ bool is_bound_method = false;
PyObject *py_func_obj = m_py_obj;
if (PyMethod_Check(py_func_obj)) {
py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
PythonObject im_self = GetAttributeValue("im_self");
if (im_self.IsValid() && !im_self.IsNone())
- result.is_bound_method = true;
+ is_bound_method = true;
} else {
// see if this is a callable object with an __call__ method
if (!PyFunction_Check(py_func_obj)) {
@@ -906,9 +884,9 @@ PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
auto __callable__ = __call__.AsType<PythonCallable>();
if (__callable__.IsValid()) {
py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
- PythonObject im_self = GetAttributeValue("im_self");
+ PythonObject im_self = __callable__.GetAttributeValue("im_self");
if (im_self.IsValid() && !im_self.IsNone())
- result.is_bound_method = true;
+ is_bound_method = true;
}
}
}
@@ -923,10 +901,27 @@ PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
result.count = code->co_argcount;
result.has_varargs = !!(code->co_flags & CO_VARARGS);
- result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
+ result.max_positional_args = result.has_varargs
+ ? ArgInfo::UNBOUNDED
+ : (result.count - (int)is_bound_method);
+
+#endif
+
return result;
}
+constexpr unsigned
+ PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17
+
+PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
+ auto arginfo = GetArgInfo();
+ if (!arginfo) {
+ llvm::consumeError(arginfo.takeError());
+ return ArgInfo{};
+ }
+ return arginfo.get();
+}
+
PythonObject PythonCallable::operator()() {
return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
}
@@ -945,21 +940,9 @@ operator()(std::initializer_list<PythonObject> args) {
PyObject_CallObject(m_py_obj, arg_tuple.get()));
}
-PythonFile::PythonFile() : PythonObject() {}
-
-PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }
-
-PythonFile::PythonFile(const char *path, const char *mode) {
- lldb_private::File file;
- FileSystem::Instance().Open(file, FileSpec(path), GetOptionsFromMode(mode));
- Reset(file, mode);
-}
-
-PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); }
-
-PythonFile::~PythonFile() {}
-
bool PythonFile::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
#if PY_MAJOR_VERSION < 3
return PyFile_Check(py_obj);
#else
@@ -967,86 +950,633 @@ bool PythonFile::Check(PyObject *py_obj) {
// first-class object type anymore. `PyFile_FromFd` is just a thin wrapper
// over `io.open()`, which returns some object derived from `io.IOBase`. As a
// result, the only way to detect a file in Python 3 is to check whether it
- // inherits from `io.IOBase`. Since it is possible for non-files to also
- // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
- // attribute, which should guarantee that it is backed by the file system.
- PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
- PythonDictionary io_dict(PyRefType::Borrowed,
- PyModule_GetDict(io_module.get()));
- PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
-
- PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
-
- if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
+ // inherits from `io.IOBase`.
+ auto io_module = PythonModule::Import("io");
+ if (!io_module) {
+ llvm::consumeError(io_module.takeError());
return false;
- if (!object_type.HasAttribute("fileno"))
+ }
+ auto iobase = io_module.get().Get("IOBase");
+ if (!iobase) {
+ llvm::consumeError(iobase.takeError());
return false;
-
- return true;
+ }
+ int r = PyObject_IsInstance(py_obj, iobase.get().get());
+ if (r < 0) {
+ llvm::consumeError(exception()); // clear the exception and log it.
+ return false;
+ }
+ return !!r;
#endif
}
-void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonFile::Check(py_obj)) {
- PythonObject::Reset();
- return;
+namespace {
+class GIL {
+public:
+ GIL() {
+ m_state = PyGILState_Ensure();
+ assert(!PyErr_Occurred());
}
+ ~GIL() { PyGILState_Release(m_state); }
+
+protected:
+ PyGILState_STATE m_state;
+};
+} // namespace
+
+const char *PythonException::toCString() const {
+ if (!m_repr_bytes)
+ return "unknown exception";
+ return PyBytes_AS_STRING(m_repr_bytes);
+}
+
+PythonException::PythonException(const char *caller) {
+ assert(PyErr_Occurred());
+ m_exception_type = m_exception = m_traceback = m_repr_bytes = NULL;
+ PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
+ PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
+ PyErr_Clear();
+ if (m_exception) {
+ PyObject *repr = PyObject_Repr(m_exception);
+ if (repr) {
+ m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr);
+ if (!m_repr_bytes) {
+ PyErr_Clear();
+ }
+ Py_XDECREF(repr);
+ } else {
+ PyErr_Clear();
+ }
+ }
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT);
+ if (caller)
+ LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString());
+ else
+ LLDB_LOGF(log, "python exception: %s", toCString());
+}
+void PythonException::Restore() {
+ if (m_exception_type && m_exception) {
+ PyErr_Restore(m_exception_type, m_exception, m_traceback);
+ } else {
+ PyErr_SetString(PyExc_Exception, toCString());
+ }
+ m_exception_type = m_exception = m_traceback = NULL;
+}
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+PythonException::~PythonException() {
+ Py_XDECREF(m_exception_type);
+ Py_XDECREF(m_exception);
+ Py_XDECREF(m_traceback);
+ Py_XDECREF(m_repr_bytes);
}
-void PythonFile::Reset(File &file, const char *mode) {
- if (!file.IsValid()) {
- Reset();
- return;
+void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); }
+
+std::error_code PythonException::convertToErrorCode() const {
+ return llvm::inconvertibleErrorCode();
+}
+
+bool PythonException::Matches(PyObject *exc) const {
+ return PyErr_GivenExceptionMatches(m_exception_type, exc);
+}
+
+const char read_exception_script[] = R"(
+import sys
+from traceback import print_exception
+if sys.version_info.major < 3:
+ from StringIO import StringIO
+else:
+ from io import StringIO
+def main(exc_type, exc_value, tb):
+ f = StringIO()
+ print_exception(exc_type, exc_value, tb, file=f)
+ return f.getvalue()
+)";
+
+std::string PythonException::ReadBacktrace() const {
+
+ if (!m_traceback)
+ return toCString();
+
+ // no need to synchronize access to this global, we already have the GIL
+ static PythonScript read_exception(read_exception_script);
+
+ Expected<std::string> backtrace = As<std::string>(
+ read_exception(m_exception_type, m_exception, m_traceback));
+
+ if (!backtrace) {
+ std::string message =
+ std::string(toCString()) + "\n" +
+ "Traceback unavailble, an error occurred while reading it:\n";
+ return (message + llvm::toString(backtrace.takeError()));
}
- char *cmode = const_cast<char *>(mode);
+ return std::move(backtrace.get());
+}
+
+char PythonException::ID = 0;
+
+llvm::Expected<File::OpenOptions>
+GetOptionsForPyObject(const PythonObject &obj) {
#if PY_MAJOR_VERSION >= 3
- Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode,
- -1, nullptr, "ignore", nullptr, 0));
+ auto options = File::OpenOptions(0);
+ auto readable = As<bool>(obj.CallMethod("readable"));
+ if (!readable)
+ return readable.takeError();
+ auto writable = As<bool>(obj.CallMethod("writable"));
+ if (!writable)
+ return writable.takeError();
+ if (readable.get())
+ options |= File::eOpenOptionRead;
+ if (writable.get())
+ options |= File::eOpenOptionWrite;
+ return options;
#else
- // Read through the Python source, doesn't seem to modify these strings
- Reset(PyRefType::Owned,
- PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode,
- nullptr));
+ PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>();
+ return File::GetOptionsFromMode(py_mode.GetString());
#endif
}
-uint32_t PythonFile::GetOptionsFromMode(llvm::StringRef mode) {
- if (mode.empty())
- return 0;
+// Base class template for python files. All it knows how to do
+// is hold a reference to the python object and close or flush it
+// when the File is closed.
+namespace {
+template <typename Base> class OwnedPythonFile : public Base {
+public:
+ template <typename... Args>
+ OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args)
+ : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
+ assert(m_py_obj);
+ }
+
+ ~OwnedPythonFile() override {
+ assert(m_py_obj);
+ GIL takeGIL;
+ Close();
+ // we need to ensure the python object is released while we still
+ // hold the GIL
+ m_py_obj.Reset();
+ }
+
+ bool IsPythonSideValid() const {
+ GIL takeGIL;
+ auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
+ if (!closed) {
+ llvm::consumeError(closed.takeError());
+ return false;
+ }
+ return !closed.get();
+ }
+
+ bool IsValid() const override {
+ return IsPythonSideValid() && Base::IsValid();
+ }
+
+ Status Close() override {
+ assert(m_py_obj);
+ Status py_error, base_error;
+ GIL takeGIL;
+ if (!m_borrowed) {
+ auto r = m_py_obj.CallMethod("close");
+ if (!r)
+ py_error = Status(r.takeError());
+ }
+ base_error = Base::Close();
+ if (py_error.Fail())
+ return py_error;
+ return base_error;
+ };
+
+ PyObject *GetPythonObject() const {
+ assert(m_py_obj.IsValid());
+ return m_py_obj.get();
+ }
+
+ static bool classof(const File *file) = delete;
+
+protected:
+ PythonFile m_py_obj;
+ bool m_borrowed;
+};
+} // namespace
+
+// A SimplePythonFile is a OwnedPythonFile that just does all I/O as
+// a NativeFile
+namespace {
+class SimplePythonFile : public OwnedPythonFile<NativeFile> {
+public:
+ SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
+ File::OpenOptions options)
+ : OwnedPythonFile(file, borrowed, fd, options, false) {}
+
+ static char ID;
+ bool isA(const void *classID) const override {
+ return classID == &ID || NativeFile::isA(classID);
+ }
+ static bool classof(const File *file) { return file->isA(&ID); }
+};
+char SimplePythonFile::ID = 0;
+} // namespace
+
+#if PY_MAJOR_VERSION >= 3
+
+namespace {
+class PythonBuffer {
+public:
+ PythonBuffer &operator=(const PythonBuffer &) = delete;
+ PythonBuffer(const PythonBuffer &) = delete;
+
+ static Expected<PythonBuffer> Create(PythonObject &obj,
+ int flags = PyBUF_SIMPLE) {
+ Py_buffer py_buffer = {};
+ PyObject_GetBuffer(obj.get(), &py_buffer, flags);
+ if (!py_buffer.obj)
+ return llvm::make_error<PythonException>();
+ return PythonBuffer(py_buffer);
+ }
+
+ PythonBuffer(PythonBuffer &&other) {
+ m_buffer = other.m_buffer;
+ other.m_buffer.obj = nullptr;
+ }
- return llvm::StringSwitch<uint32_t>(mode.str())
- .Case("r", File::eOpenOptionRead)
- .Case("w", File::eOpenOptionWrite)
- .Case("a", File::eOpenOptionWrite | File::eOpenOptionAppend |
- File::eOpenOptionCanCreate)
- .Case("r+", File::eOpenOptionRead | File::eOpenOptionWrite)
- .Case("w+", File::eOpenOptionRead | File::eOpenOptionWrite |
- File::eOpenOptionCanCreate | File::eOpenOptionTruncate)
- .Case("a+", File::eOpenOptionRead | File::eOpenOptionWrite |
- File::eOpenOptionAppend | File::eOpenOptionCanCreate)
- .Default(0);
+ ~PythonBuffer() {
+ if (m_buffer.obj)
+ PyBuffer_Release(&m_buffer);
+ }
+
+ Py_buffer &get() { return m_buffer; }
+
+private:
+ // takes ownership of the buffer.
+ PythonBuffer(const Py_buffer &py_buffer) : m_buffer(py_buffer) {}
+ Py_buffer m_buffer;
+};
+} // namespace
+
+// Shared methods between TextPythonFile and BinaryPythonFile
+namespace {
+class PythonIOFile : public OwnedPythonFile<File> {
+public:
+ PythonIOFile(const PythonFile &file, bool borrowed)
+ : OwnedPythonFile(file, borrowed) {}
+
+ ~PythonIOFile() override { Close(); }
+
+ bool IsValid() const override { return IsPythonSideValid(); }
+
+ Status Close() override {
+ assert(m_py_obj);
+ GIL takeGIL;
+ if (m_borrowed)
+ return Flush();
+ auto r = m_py_obj.CallMethod("close");
+ if (!r)
+ return Status(r.takeError());
+ return Status();
+ }
+
+ Status Flush() override {
+ GIL takeGIL;
+ auto r = m_py_obj.CallMethod("flush");
+ if (!r)
+ return Status(r.takeError());
+ return Status();
+ }
+
+ Expected<File::OpenOptions> GetOptions() const override {
+ GIL takeGIL;
+ return GetOptionsForPyObject(m_py_obj);
+ }
+
+ static char ID;
+ bool isA(const void *classID) const override {
+ return classID == &ID || File::isA(classID);
+ }
+ static bool classof(const File *file) { return file->isA(&ID); }
+};
+char PythonIOFile::ID = 0;
+} // namespace
+
+namespace {
+class BinaryPythonFile : public PythonIOFile {
+protected:
+ int m_descriptor;
+
+public:
+ BinaryPythonFile(int fd, const PythonFile &file, bool borrowed)
+ : PythonIOFile(file, borrowed),
+ m_descriptor(File::DescriptorIsValid(fd) ? fd
+ : File::kInvalidDescriptor) {}
+
+ int GetDescriptor() const override { return m_descriptor; }
+
+ Status Write(const void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ PyObject *pybuffer_p = PyMemoryView_FromMemory(
+ const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ);
+ if (!pybuffer_p)
+ return Status(llvm::make_error<PythonException>());
+ auto pybuffer = Take<PythonObject>(pybuffer_p);
+ num_bytes = 0;
+ auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer));
+ if (!bytes_written)
+ return Status(bytes_written.takeError());
+ if (bytes_written.get() < 0)
+ return Status(".write() method returned a negative number!");
+ static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
+ num_bytes = bytes_written.get();
+ return Status();
+ }
+
+ Status Read(void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
+ auto pybuffer_obj =
+ m_py_obj.CallMethod("read", (unsigned long long)num_bytes);
+ if (!pybuffer_obj)
+ return Status(pybuffer_obj.takeError());
+ num_bytes = 0;
+ if (pybuffer_obj.get().IsNone()) {
+ // EOF
+ num_bytes = 0;
+ return Status();
+ }
+ auto pybuffer = PythonBuffer::Create(pybuffer_obj.get());
+ if (!pybuffer)
+ return Status(pybuffer.takeError());
+ memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len);
+ num_bytes = pybuffer.get().get().len;
+ return Status();
+ }
+};
+} // namespace
+
+namespace {
+class TextPythonFile : public PythonIOFile {
+protected:
+ int m_descriptor;
+
+public:
+ TextPythonFile(int fd, const PythonFile &file, bool borrowed)
+ : PythonIOFile(file, borrowed),
+ m_descriptor(File::DescriptorIsValid(fd) ? fd
+ : File::kInvalidDescriptor) {}
+
+ int GetDescriptor() const override { return m_descriptor; }
+
+ Status Write(const void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ auto pystring =
+ PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes));
+ if (!pystring)
+ return Status(pystring.takeError());
+ num_bytes = 0;
+ auto bytes_written =
+ As<long long>(m_py_obj.CallMethod("write", pystring.get()));
+ if (!bytes_written)
+ return Status(bytes_written.takeError());
+ if (bytes_written.get() < 0)
+ return Status(".write() method returned a negative number!");
+ static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
+ num_bytes = bytes_written.get();
+ return Status();
+ }
+
+ Status Read(void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ size_t num_chars = num_bytes / 6;
+ size_t orig_num_bytes = num_bytes;
+ num_bytes = 0;
+ if (orig_num_bytes < 6) {
+ return Status("can't read less than 6 bytes from a utf8 text stream");
+ }
+ auto pystring = As<PythonString>(
+ m_py_obj.CallMethod("read", (unsigned long long)num_chars));
+ if (!pystring)
+ return Status(pystring.takeError());
+ if (pystring.get().IsNone()) {
+ // EOF
+ return Status();
+ }
+ auto stringref = pystring.get().AsUTF8();
+ if (!stringref)
+ return Status(stringref.takeError());
+ num_bytes = stringref.get().size();
+ memcpy(buf, stringref.get().begin(), num_bytes);
+ return Status();
+ }
+};
+} // namespace
+
+#endif
+
+llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
+ if (!IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid PythonFile");
+
+ int fd = PyObject_AsFileDescriptor(m_py_obj);
+ if (fd < 0) {
+ PyErr_Clear();
+ return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
+ }
+ auto options = GetOptionsForPyObject(*this);
+ if (!options)
+ return options.takeError();
+
+ // LLDB and python will not share I/O buffers. We should probably
+ // flush the python buffers now.
+ auto r = CallMethod("flush");
+ if (!r)
+ return r.takeError();
+
+ FileSP file_sp;
+ if (borrowed) {
+ // In this case we we don't need to retain the python
+ // object at all.
+ file_sp = std::make_shared<NativeFile>(fd, options.get(), false);
+ } else {
+ file_sp = std::static_pointer_cast<File>(
+ std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get()));
+ }
+ if (!file_sp->IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid File");
+
+ return file_sp;
}
-bool PythonFile::GetUnderlyingFile(File &file) const {
+llvm::Expected<FileSP>
+PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) {
+
+ assert(!PyErr_Occurred());
+
if (!IsValid())
- return false;
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid PythonFile");
+
+#if PY_MAJOR_VERSION < 3
+
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "not supported on python 2");
+
+#else
+
+ int fd = PyObject_AsFileDescriptor(m_py_obj);
+ if (fd < 0) {
+ PyErr_Clear();
+ fd = File::kInvalidDescriptor;
+ }
+
+ auto io_module = PythonModule::Import("io");
+ if (!io_module)
+ return io_module.takeError();
+ auto textIOBase = io_module.get().Get("TextIOBase");
+ if (!textIOBase)
+ return textIOBase.takeError();
+ auto rawIOBase = io_module.get().Get("RawIOBase");
+ if (!rawIOBase)
+ return rawIOBase.takeError();
+ auto bufferedIOBase = io_module.get().Get("BufferedIOBase");
+ if (!bufferedIOBase)
+ return bufferedIOBase.takeError();
+
+ FileSP file_sp;
+
+ auto isTextIO = IsInstance(textIOBase.get());
+ if (!isTextIO)
+ return isTextIO.takeError();
+ if (isTextIO.get())
+ file_sp = std::static_pointer_cast<File>(
+ std::make_shared<TextPythonFile>(fd, *this, borrowed));
+
+ auto isRawIO = IsInstance(rawIOBase.get());
+ if (!isRawIO)
+ return isRawIO.takeError();
+ auto isBufferedIO = IsInstance(bufferedIOBase.get());
+ if (!isBufferedIO)
+ return isBufferedIO.takeError();
+
+ if (isRawIO.get() || isBufferedIO.get()) {
+ file_sp = std::static_pointer_cast<File>(
+ std::make_shared<BinaryPythonFile>(fd, *this, borrowed));
+ }
+
+ if (!file_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "python file is neither text nor binary");
+
+ if (!file_sp->IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid File");
+
+ return file_sp;
+
+#endif
+}
+
+Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
+ if (!file.IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid file");
+
+ if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
+ return Retain<PythonFile>(simple->GetPythonObject());
+#if PY_MAJOR_VERSION >= 3
+ if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
+ return Retain<PythonFile>(pythonio->GetPythonObject());
+#endif
+
+ if (!mode) {
+ auto m = file.GetOpenMode();
+ if (!m)
+ return m.takeError();
+ mode = m.get();
+ }
+
+ PyObject *file_obj;
+#if PY_MAJOR_VERSION >= 3
+ file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr,
+ "ignore", nullptr, 0);
+#else
+ // Read through the Python source, doesn't seem to modify these strings
+ char *cmode = const_cast<char *>(mode);
+ // We pass ::flush instead of ::fclose here so we borrow the FILE* --
+ // the lldb_private::File still owns it.
+ file_obj =
+ PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, ::fflush);
+#endif
+
+ if (!file_obj)
+ return exception();
+
+ return Take<PythonFile>(file_obj);
+}
+
+Error PythonScript::Init() {
+ if (function.IsValid())
+ return Error::success();
+
+ PythonDictionary globals(PyInitialValue::Empty);
+ auto builtins = PythonModule::BuiltinsModule();
+ if (Error error = globals.SetItem("__builtins__", builtins))
+ return error;
+ PyObject *o =
+ PyRun_String(script, Py_file_input, globals.get(), globals.get());
+ if (!o)
+ return exception();
+ Take<PythonObject>(o);
+ auto f = As<PythonCallable>(globals.GetItem("main"));
+ if (!f)
+ return f.takeError();
+ function = std::move(f.get());
+
+ return Error::success();
+}
+
+llvm::Expected<PythonObject>
+python::runStringOneLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals) {
+ if (!globals.IsValid() || !locals.IsValid())
+ return nullDeref();
+
+ PyObject *code =
+ Py_CompileString(NullTerminated(string), "<string>", Py_eval_input);
+ if (!code) {
+ PyErr_Clear();
+ code =
+ Py_CompileString(NullTerminated(string), "<string>", Py_single_input);
+ }
+ if (!code)
+ return exception();
+ auto code_ref = Take<PythonObject>(code);
+
+#if PY_MAJOR_VERSION < 3
+ PyObject *result =
+ PyEval_EvalCode((PyCodeObject *)code, globals.get(), locals.get());
+#else
+ PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
+#endif
+
+ if (!result)
+ return exception();
+
+ return Take<PythonObject>(result);
+}
- file.Close();
- // We don't own the file descriptor returned by this function, make sure the
- // File object knows about that.
- file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
- PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
- file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
- return file.IsValid();
+llvm::Expected<PythonObject>
+python::runStringMultiLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals) {
+ if (!globals.IsValid() || !locals.IsValid())
+ return nullDeref();
+ PyObject *result = PyRun_String(NullTerminated(string), Py_file_input,
+ globals.get(), locals.get());
+ if (!result)
+ return exception();
+ return Take<PythonObject>(result);
}
#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 049ce90bb1b1..373d3212697d 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -6,6 +6,45 @@
//
//===----------------------------------------------------------------------===//
+//
+// !! FIXME FIXME FIXME !!
+//
+// Python APIs nearly all can return an exception. They do this
+// by returning NULL, or -1, or some such value and setting
+// the exception state with PyErr_Set*(). Exceptions must be
+// handled before further python API functions are called. Failure
+// to do so will result in asserts on debug builds of python.
+// It will also sometimes, but not usually result in crashes of
+// release builds.
+//
+// Nearly all the code in this header does not handle python exceptions
+// correctly. It should all be converted to return Expected<> or
+// Error types to capture the exception.
+//
+// Everything in this file except functions that return Error or
+// Expected<> is considered deprecated and should not be
+// used in new code. If you need to use it, fix it first.
+//
+//
+// TODOs for this file
+//
+// * Make all methods safe for exceptions.
+//
+// * Eliminate method signatures that must translate exceptions into
+// empty objects or NULLs. Almost everything here should return
+// Expected<>. It should be acceptable for certain operations that
+// can never fail to assert instead, such as the creation of
+// PythonString from a string literal.
+//
+// * Elimintate Reset(), and make all non-default constructors private.
+// Python objects should be created with Retain<> or Take<>, and they
+// should be assigned with operator=
+//
+// * Eliminate default constructors, make python objects always
+// nonnull, and use optionals where necessary.
+//
+
+
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
@@ -20,12 +59,15 @@
#include "llvm/ADT/ArrayRef.h"
namespace lldb_private {
+namespace python {
+class PythonObject;
class PythonBytes;
class PythonString;
class PythonList;
class PythonDictionary;
class PythonInteger;
+class PythonException;
class StructuredPythonObject : public StructuredData::Generic {
public:
@@ -43,7 +85,7 @@ public:
bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
private:
DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
@@ -72,61 +114,137 @@ enum class PyRefType {
// not call Py_INCREF.
};
-enum class PyInitialValue { Invalid, Empty };
-class PythonObject {
-public:
- PythonObject() : m_py_obj(nullptr) {}
+// Take a reference that you already own, and turn it into
+// a PythonObject.
+//
+// Most python API methods will return a +1 reference
+// if they succeed or NULL if and only if
+// they set an exception. Use this to collect such return
+// values, after checking for NULL.
+//
+// If T is not just PythonObject, then obj must be already be
+// checked to be of the correct type.
+template <typename T> T Take(PyObject *obj) {
+ assert(obj);
+ assert(!PyErr_Occurred());
+ T thing(PyRefType::Owned, obj);
+ assert(thing.IsValid());
+ return std::move(thing);
+}
+
+// Retain a reference you have borrowed, and turn it into
+// a PythonObject.
+//
+// A minority of python APIs return a borrowed reference
+// instead of a +1. They will also return NULL if and only
+// if they set an exception. Use this to collect such return
+// values, after checking for NULL.
+//
+// If T is not just PythonObject, then obj must be already be
+// checked to be of the correct type.
+template <typename T> T Retain(PyObject *obj) {
+ assert(obj);
+ assert(!PyErr_Occurred());
+ T thing(PyRefType::Borrowed, obj);
+ assert(thing.IsValid());
+ return std::move(thing);
+}
+
+// This class can be used like a utility function to convert from
+// a llvm-friendly Twine into a null-terminated const char *,
+// which is the form python C APIs want their strings in.
+//
+// Example:
+// const llvm::Twine &some_twine;
+// PyFoo_Bar(x, y, z, NullTerminated(some_twine));
+//
+// Why a class instead of a function? If the twine isn't already null
+// terminated, it will need a temporary buffer to copy the string
+// into. We need that buffer to stick around for the lifetime of the
+// statement.
+class NullTerminated {
+ const char *str;
+ llvm::SmallString<32> storage;
- PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) {
- Reset(type, py_obj);
+public:
+ NullTerminated(const llvm::Twine &twine) {
+ llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
+ str = ref.begin();
}
+ operator const char *() { return str; }
+};
- PythonObject(const PythonObject &rhs) : m_py_obj(nullptr) { Reset(rhs); }
+inline llvm::Error nullDeref() {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "A NULL PyObject* was dereferenced");
+}
- virtual ~PythonObject() { Reset(); }
+inline llvm::Error exception(const char *s = nullptr) {
+ return llvm::make_error<PythonException>(s);
+}
- void Reset() {
- // Avoid calling the virtual method since it's not necessary
- // to actually validate the type of the PyObject if we're
- // just setting to null.
- if (Py_IsInitialized())
- Py_XDECREF(m_py_obj);
- m_py_obj = nullptr;
- }
+inline llvm::Error keyError() {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "key not in dict");
+}
- void Reset(const PythonObject &rhs) {
- // Avoid calling the virtual method if it's not necessary
- // to actually validate the type of the PyObject.
- if (!rhs.IsValid())
- Reset();
- else
- Reset(PyRefType::Borrowed, rhs.m_py_obj);
- }
+enum class PyInitialValue { Invalid, Empty };
- // PythonObject is implicitly convertible to PyObject *, which will call the
- // wrong overload. We want to explicitly disallow this, since a PyObject
- // *always* owns its reference. Therefore the overload which takes a
- // PyRefType doesn't make sense, and the copy constructor should be used.
- void Reset(PyRefType type, const PythonObject &ref) = delete;
+template <typename T, typename Enable = void> struct PythonFormat;
- virtual void Reset(PyRefType type, PyObject *py_obj) {
- if (py_obj == m_py_obj)
- return;
+template <> struct PythonFormat<unsigned long long> {
+ static constexpr char format = 'K';
+ static auto get(unsigned long long value) { return value; }
+};
- if (Py_IsInitialized())
- Py_XDECREF(m_py_obj);
+template <> struct PythonFormat<long long> {
+ static constexpr char format = 'L';
+ static auto get(long long value) { return value; }
+};
- m_py_obj = py_obj;
+template <> struct PythonFormat<PyObject *> {
+ static constexpr char format = 'O';
+ static auto get(PyObject *value) { return value; }
+};
+
+template <typename T>
+struct PythonFormat<
+ T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
+ static constexpr char format = 'O';
+ static auto get(const T &value) { return value.get(); }
+};
+
+class PythonObject {
+public:
+ PythonObject() : m_py_obj(nullptr) {}
+ PythonObject(PyRefType type, PyObject *py_obj) {
+ m_py_obj = py_obj;
// If this is a borrowed reference, we need to convert it to
// an owned reference by incrementing it. If it is an owned
// reference (for example the caller allocated it with PyDict_New()
// then we must *not* increment it.
- if (Py_IsInitialized() && type == PyRefType::Borrowed)
+ if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
Py_XINCREF(m_py_obj);
}
+ PythonObject(const PythonObject &rhs)
+ : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
+
+ PythonObject(PythonObject &&rhs) {
+ m_py_obj = rhs.m_py_obj;
+ rhs.m_py_obj = nullptr;
+ }
+
+ ~PythonObject() { Reset(); }
+
+ void Reset() {
+ if (m_py_obj && Py_IsInitialized())
+ Py_DECREF(m_py_obj);
+ m_py_obj = nullptr;
+ }
+
void Dump() const {
if (m_py_obj)
_PyObject_Dump(m_py_obj);
@@ -144,8 +262,9 @@ public:
return result;
}
- PythonObject &operator=(const PythonObject &other) {
- Reset(PyRefType::Borrowed, other.get());
+ PythonObject &operator=(PythonObject other) {
+ Reset();
+ m_py_obj = std::exchange(other.m_py_obj, nullptr);
return *this;
}
@@ -174,11 +293,13 @@ public:
PythonObject GetAttributeValue(llvm::StringRef attribute) const;
- bool IsValid() const;
+ bool IsNone() const { return m_py_obj == Py_None; }
+
+ bool IsValid() const { return m_py_obj != nullptr; }
- bool IsAllocated() const;
+ bool IsAllocated() const { return IsValid() && !IsNone(); }
- bool IsNone() const;
+ explicit operator bool() const { return IsValid() && !IsNone(); }
template <typename T> T AsType() const {
if (!T::Check(m_py_obj))
@@ -189,24 +310,125 @@ public:
StructuredData::ObjectSP CreateStructuredObject() const;
protected:
+
+#if PY_MAJOR_VERSION < 3
+ // The python 2 API declares some arguments as char* that should
+ // be const char *, but it doesn't actually modify them.
+ static char *py2_const_cast(const char *s) { return const_cast<char *>(s); }
+#else
+ static const char *py2_const_cast(const char *s) { return s; }
+#endif
+
+public:
+ template <typename... T>
+ llvm::Expected<PythonObject> CallMethod(const char *name,
+ const T &... t) const {
+ const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
+ PyObject *obj =
+ PyObject_CallMethod(m_py_obj, py2_const_cast(name),
+ py2_const_cast(format), PythonFormat<T>::get(t)...);
+ if (!obj)
+ return exception();
+ return python::Take<PythonObject>(obj);
+ }
+
+ template <typename... T>
+ llvm::Expected<PythonObject> Call(const T &... t) const {
+ const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
+ PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
+ PythonFormat<T>::get(t)...);
+ if (!obj)
+ return exception();
+ return python::Take<PythonObject>(obj);
+ }
+
+ llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
+ if (!m_py_obj)
+ return nullDeref();
+ PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
+ if (!obj)
+ return exception();
+ return python::Take<PythonObject>(obj);
+ }
+
+ llvm::Expected<bool> IsTrue() {
+ if (!m_py_obj)
+ return nullDeref();
+ int r = PyObject_IsTrue(m_py_obj);
+ if (r < 0)
+ return exception();
+ return !!r;
+ }
+
+ llvm::Expected<long long> AsLongLong() {
+ if (!m_py_obj)
+ return nullDeref();
+ assert(!PyErr_Occurred());
+ long long r = PyLong_AsLongLong(m_py_obj);
+ if (PyErr_Occurred())
+ return exception();
+ return r;
+ }
+
+ llvm::Expected<bool> IsInstance(const PythonObject &cls) {
+ if (!m_py_obj || !cls.IsValid())
+ return nullDeref();
+ int r = PyObject_IsInstance(m_py_obj, cls.get());
+ if (r < 0)
+ return exception();
+ return !!r;
+ }
+
+protected:
PyObject *m_py_obj;
};
-class PythonBytes : public PythonObject {
+
+// This is why C++ needs monads.
+template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ if (!T::Check(obj.get().get()))
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "type error");
+ return T(PyRefType::Borrowed, std::move(obj.get().get()));
+}
+
+template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
+
+template <>
+llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
+
+template <>
+llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
+
+
+template <class T> class TypedPythonObject : public PythonObject {
public:
- PythonBytes();
- explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
- PythonBytes(const uint8_t *bytes, size_t length);
- PythonBytes(PyRefType type, PyObject *o);
+ // override to perform implicit type conversions on Reset
+ // This can be eliminated once we drop python 2 support.
+ static void Convert(PyRefType &type, PyObject *&py_obj) {}
- ~PythonBytes() override;
+ TypedPythonObject(PyRefType type, PyObject *py_obj) {
+ if (!py_obj)
+ return;
+ T::Convert(type, py_obj);
+ if (T::Check(py_obj))
+ PythonObject::operator=(PythonObject(type, py_obj));
+ else if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ }
- static bool Check(PyObject *py_obj);
+ TypedPythonObject() {}
+};
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+class PythonBytes : public TypedPythonObject<PythonBytes> {
+public:
+ using TypedPythonObject::TypedPythonObject;
+ explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
+ PythonBytes(const uint8_t *bytes, size_t length);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ static bool Check(PyObject *py_obj);
llvm::ArrayRef<uint8_t> GetBytes() const;
@@ -217,23 +439,15 @@ public:
StructuredData::StringSP CreateStructuredString() const;
};
-class PythonByteArray : public PythonObject {
+class PythonByteArray : public TypedPythonObject<PythonByteArray> {
public:
- PythonByteArray();
+ using TypedPythonObject::TypedPythonObject;
explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
PythonByteArray(const uint8_t *bytes, size_t length);
- PythonByteArray(PyRefType type, PyObject *o);
PythonByteArray(const PythonBytes &object);
- ~PythonByteArray() override;
-
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
llvm::ArrayRef<uint8_t> GetBytes() const;
size_t GetSize() const;
@@ -243,45 +457,39 @@ public:
StructuredData::StringSP CreateStructuredString() const;
};
-class PythonString : public PythonObject {
+class PythonString : public TypedPythonObject<PythonString> {
public:
- PythonString();
- explicit PythonString(llvm::StringRef string);
- explicit PythonString(const char *string);
- PythonString(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
+ static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
- ~PythonString() override;
+ PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
- static bool Check(PyObject *py_obj);
+ explicit PythonString(llvm::StringRef string); // safe, null on error
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ static bool Check(PyObject *py_obj);
+ static void Convert(PyRefType &type, PyObject *&py_obj);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ llvm::StringRef GetString() const; // safe, empty string on error
- llvm::StringRef GetString() const;
+ llvm::Expected<llvm::StringRef> AsUTF8() const;
size_t GetSize() const;
- void SetString(llvm::StringRef string);
+ void SetString(llvm::StringRef string); // safe, null on error
StructuredData::StringSP CreateStructuredString() const;
};
-class PythonInteger : public PythonObject {
+class PythonInteger : public TypedPythonObject<PythonInteger> {
public:
- PythonInteger();
- explicit PythonInteger(int64_t value);
- PythonInteger(PyRefType type, PyObject *o);
-
- ~PythonInteger() override;
+ using TypedPythonObject::TypedPythonObject;
- static bool Check(PyObject *py_obj);
+ PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ explicit PythonInteger(int64_t value);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ static bool Check(PyObject *py_obj);
+ static void Convert(PyRefType &type, PyObject *&py_obj);
int64_t GetInteger() const;
@@ -290,21 +498,14 @@ public:
StructuredData::IntegerSP CreateStructuredInteger() const;
};
-class PythonBoolean : public PythonObject {
+class PythonBoolean : public TypedPythonObject<PythonBoolean> {
public:
- PythonBoolean() = default;
- explicit PythonBoolean(bool value);
- PythonBoolean(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
- ~PythonBoolean() override = default;
+ explicit PythonBoolean(bool value);
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
bool GetValue() const;
void SetValue(bool value);
@@ -312,22 +513,17 @@ public:
StructuredData::BooleanSP CreateStructuredBoolean() const;
};
-class PythonList : public PythonObject {
+class PythonList : public TypedPythonObject<PythonList> {
public:
- PythonList() {}
+ using TypedPythonObject::TypedPythonObject;
+
+ PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
+
explicit PythonList(PyInitialValue value);
explicit PythonList(int list_size);
- PythonList(PyRefType type, PyObject *o);
-
- ~PythonList() override;
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
uint32_t GetSize() const;
PythonObject GetItemAtIndex(uint32_t index) const;
@@ -339,24 +535,17 @@ public:
StructuredData::ArraySP CreateStructuredArray() const;
};
-class PythonTuple : public PythonObject {
+class PythonTuple : public TypedPythonObject<PythonTuple> {
public:
- PythonTuple() {}
+ using TypedPythonObject::TypedPythonObject;
+
explicit PythonTuple(PyInitialValue value);
explicit PythonTuple(int tuple_size);
- PythonTuple(PyRefType type, PyObject *o);
PythonTuple(std::initializer_list<PythonObject> objects);
PythonTuple(std::initializer_list<PyObject *> objects);
- ~PythonTuple() override;
-
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
uint32_t GetSize() const;
PythonObject GetItemAtIndex(uint32_t index) const;
@@ -366,37 +555,35 @@ public:
StructuredData::ArraySP CreateStructuredArray() const;
};
-class PythonDictionary : public PythonObject {
+class PythonDictionary : public TypedPythonObject<PythonDictionary> {
public:
- PythonDictionary() {}
- explicit PythonDictionary(PyInitialValue value);
- PythonDictionary(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
- ~PythonDictionary() override;
-
- static bool Check(PyObject *py_obj);
+ PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ explicit PythonDictionary(PyInitialValue value);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ static bool Check(PyObject *py_obj);
uint32_t GetSize() const;
PythonList GetKeys() const;
- PythonObject GetItemForKey(const PythonObject &key) const;
- void SetItemForKey(const PythonObject &key, const PythonObject &value);
+ PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
+ void SetItemForKey(const PythonObject &key,
+ const PythonObject &value); // DEPRECATED
+
+ llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
+ llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
+ llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
+ llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
StructuredData::DictionarySP CreateStructuredDictionary() const;
};
-class PythonModule : public PythonObject {
+class PythonModule : public TypedPythonObject<PythonModule> {
public:
- PythonModule();
- PythonModule(PyRefType type, PyObject *o);
-
- ~PythonModule() override;
+ using TypedPythonObject::TypedPythonObject;
static bool Check(PyObject *py_obj);
@@ -406,38 +593,57 @@ public:
static PythonModule AddModule(llvm::StringRef module);
- static PythonModule ImportModule(llvm::StringRef module);
+ // safe, returns invalid on error;
+ static PythonModule ImportModule(llvm::StringRef name) {
+ std::string s = name;
+ auto mod = Import(s.c_str());
+ if (!mod) {
+ llvm::consumeError(mod.takeError());
+ return PythonModule();
+ }
+ return std::move(mod.get());
+ }
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ llvm::Expected<PythonObject> Get(const llvm::Twine &name);
PythonDictionary GetDictionary() const;
};
-class PythonCallable : public PythonObject {
+class PythonCallable : public TypedPythonObject<PythonCallable> {
public:
+ using TypedPythonObject::TypedPythonObject;
+
struct ArgInfo {
- size_t count;
- bool is_bound_method : 1;
- bool has_varargs : 1;
- bool has_kwargs : 1;
+ /* the largest number of positional arguments this callable
+ * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
+ * function and can accept an arbitrary number */
+ unsigned max_positional_args;
+ static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
+ /* the number of positional arguments, including optional ones,
+ * and excluding varargs. If this is a bound method, then the
+ * count will still include a +1 for self.
+ *
+ * FIXME. That's crazy. This should be replaced with
+ * an accurate min and max for positional args.
+ */
+ int count;
+ /* does the callable have positional varargs? */
+ bool has_varargs : 1; // FIXME delete this
};
- PythonCallable();
- PythonCallable(PyRefType type, PyObject *o);
-
- ~PythonCallable() override;
-
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ llvm::Expected<ArgInfo> GetArgInfo() const;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ llvm::Expected<ArgInfo> GetInitArgInfo() const;
- ArgInfo GetNumArguments() const;
+ ArgInfo GetNumArguments() const; // DEPRECATED
+
+ // If the callable is a Py_Class, then find the number of arguments
+ // of the __init__ method.
+ ArgInfo GetNumInitArguments() const; // DEPRECATED
PythonObject operator()();
@@ -451,27 +657,123 @@ public:
}
};
-class PythonFile : public PythonObject {
+class PythonFile : public TypedPythonObject<PythonFile> {
public:
- PythonFile();
- PythonFile(File &file, const char *mode);
- PythonFile(const char *path, const char *mode);
- PythonFile(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
- ~PythonFile() override;
+ PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
static bool Check(PyObject *py_obj);
- using PythonObject::Reset;
+ static llvm::Expected<PythonFile> FromFile(File &file,
+ const char *mode = nullptr);
- void Reset(PyRefType type, PyObject *py_obj) override;
- void Reset(File &file, const char *mode);
+ llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
+ llvm::Expected<lldb::FileSP>
+ ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
+};
- static uint32_t GetOptionsFromMode(llvm::StringRef mode);
+class PythonException : public llvm::ErrorInfo<PythonException> {
+private:
+ PyObject *m_exception_type, *m_exception, *m_traceback;
+ PyObject *m_repr_bytes;
- bool GetUnderlyingFile(File &file) const;
+public:
+ static char ID;
+ const char *toCString() const;
+ PythonException(const char *caller = nullptr);
+ void Restore();
+ ~PythonException();
+ void log(llvm::raw_ostream &OS) const override;
+ std::error_code convertToErrorCode() const override;
+ bool Matches(PyObject *exc) const;
+ std::string ReadBacktrace() const;
+};
+
+// This extracts the underlying T out of an Expected<T> and returns it.
+// If the Expected is an Error instead of a T, that error will be converted
+// into a python exception, and this will return a default-constructed T.
+//
+// This is appropriate for use right at the boundary of python calling into
+// C++, such as in a SWIG typemap. In such a context you should simply
+// check if the returned T is valid, and if it is, return a NULL back
+// to python. This will result in the Error being raised as an exception
+// from python code's point of view.
+//
+// For example:
+// ```
+// Expected<Foo *> efoop = some_cpp_function();
+// Foo *foop = unwrapOrSetPythonException(efoop);
+// if (!foop)
+// return NULL;
+// do_something(*foop);
+//
+// If the Error returned was itself created because a python exception was
+// raised when C++ code called into python, then the original exception
+// will be restored. Otherwise a simple string exception will be raised.
+template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
+ if (expected)
+ return expected.get();
+ llvm::handleAllErrors(
+ expected.takeError(), [](PythonException &E) { E.Restore(); },
+ [](const llvm::ErrorInfoBase &E) {
+ PyErr_SetString(PyExc_Exception, E.message().c_str());
+ });
+ return T();
+}
+
+// This is only here to help incrementally migrate old, exception-unsafe
+// code.
+template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
+ if (expected)
+ return std::move(expected.get());
+ llvm::consumeError(expected.takeError());
+ return T();
+}
+
+llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals);
+
+llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals);
+
+// Sometimes the best way to interact with a python interpreter is
+// to run some python code. You construct a PythonScript with
+// script string. The script assigns some function to `_function_`
+// and you get a C++ callable object that calls the python function.
+//
+// Example:
+//
+// const char script[] = R"(
+// def main(x, y):
+// ....
+// )";
+//
+// Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
+// // no need to synchronize access to this global, we already have the GIL
+// static PythonScript foo(script)
+// return foo(x, y);
+// }
+class PythonScript {
+ const char *script;
+ PythonCallable function;
+
+ llvm::Error Init();
+
+public:
+ PythonScript(const char *script) : script(script), function() {}
+
+ template <typename... Args>
+ llvm::Expected<PythonObject> operator()(Args &&... args) {
+ if (llvm::Error error = Init())
+ return std::move(error);
+ return function.Call(std::forward<Args>(args)...);
+ }
};
+} // namespace python
} // namespace lldb_private
#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
deleted file mode 100644
index c9d834ce6868..000000000000
--- a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- PythonExceptionState.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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_DISABLE_PYTHON
-
-// LLDB Python header must be included first
-#include "lldb-python.h"
-
-#include "PythonExceptionState.h"
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb_private;
-
-PythonExceptionState::PythonExceptionState(bool restore_on_exit)
- : m_restore_on_exit(restore_on_exit) {
- Acquire(restore_on_exit);
-}
-
-PythonExceptionState::~PythonExceptionState() {
- if (m_restore_on_exit)
- Restore();
-}
-
-void PythonExceptionState::Acquire(bool restore_on_exit) {
- // If a state is already acquired, the user needs to decide whether they want
- // to discard or restore it. Don't allow the potential silent loss of a
- // valid state.
- assert(!IsError());
-
- if (!HasErrorOccurred())
- return;
-
- PyObject *py_type = nullptr;
- PyObject *py_value = nullptr;
- PyObject *py_traceback = nullptr;
- PyErr_Fetch(&py_type, &py_value, &py_traceback);
- // PyErr_Fetch clears the error flag.
- assert(!HasErrorOccurred());
-
- // Ownership of the objects returned by `PyErr_Fetch` is transferred to us.
- m_type.Reset(PyRefType::Owned, py_type);
- m_value.Reset(PyRefType::Owned, py_value);
- m_traceback.Reset(PyRefType::Owned, py_traceback);
- m_restore_on_exit = restore_on_exit;
-}
-
-void PythonExceptionState::Restore() {
- if (m_type.IsValid()) {
- // The documentation for PyErr_Restore says "Do not pass a null type and
- // non-null value or traceback. So only restore if type was non-null to
- // begin with. In this case we're passing ownership back to Python so
- // release them all.
- PyErr_Restore(m_type.release(), m_value.release(), m_traceback.release());
- }
-
- // After we restore, we should not hold onto the exception state. Demand
- // that it be re-acquired.
- Discard();
-}
-
-void PythonExceptionState::Discard() {
- m_type.Reset();
- m_value.Reset();
- m_traceback.Reset();
-}
-
-void PythonExceptionState::Reset() {
- if (m_restore_on_exit)
- Restore();
- else
- Discard();
-}
-
-bool PythonExceptionState::HasErrorOccurred() { return PyErr_Occurred(); }
-
-bool PythonExceptionState::IsError() const {
- return m_type.IsValid() || m_value.IsValid() || m_traceback.IsValid();
-}
-
-PythonObject PythonExceptionState::GetType() const { return m_type; }
-
-PythonObject PythonExceptionState::GetValue() const { return m_value; }
-
-PythonObject PythonExceptionState::GetTraceback() const { return m_traceback; }
-
-std::string PythonExceptionState::Format() const {
- // Don't allow this function to modify the error state.
- PythonExceptionState state(true);
-
- std::string backtrace = ReadBacktrace();
- if (!IsError())
- return std::string();
-
- // It's possible that ReadPythonBacktrace generated another exception. If
- // this happens we have to clear the exception, because otherwise
- // PyObject_Str() will assert below. That's why we needed to do the save /
- // restore at the beginning of this function.
- PythonExceptionState bt_error_state(false);
-
- std::string error_string;
- llvm::raw_string_ostream error_stream(error_string);
- error_stream << m_value.Str().GetString() << "\n";
-
- if (!bt_error_state.IsError()) {
- // If we were able to read the backtrace, just append it.
- error_stream << backtrace << "\n";
- } else {
- // Otherwise, append some information about why we were unable to obtain
- // the backtrace.
- PythonString bt_error = bt_error_state.GetValue().Str();
- error_stream << "An error occurred while retrieving the backtrace: "
- << bt_error.GetString() << "\n";
- }
- return error_stream.str();
-}
-
-std::string PythonExceptionState::ReadBacktrace() const {
- std::string retval("backtrace unavailable");
-
- auto traceback_module = PythonModule::ImportModule("traceback");
-#if PY_MAJOR_VERSION >= 3
- auto stringIO_module = PythonModule::ImportModule("io");
-#else
- auto stringIO_module = PythonModule::ImportModule("StringIO");
-#endif
- if (!m_traceback.IsAllocated())
- return retval;
-
- if (!traceback_module.IsAllocated() || !stringIO_module.IsAllocated())
- return retval;
-
- auto stringIO_builder =
- stringIO_module.ResolveName<PythonCallable>("StringIO");
- if (!stringIO_builder.IsAllocated())
- return retval;
-
- auto stringIO_buffer = stringIO_builder();
- if (!stringIO_buffer.IsAllocated())
- return retval;
-
- auto printTB = traceback_module.ResolveName<PythonCallable>("print_tb");
- if (!printTB.IsAllocated())
- return retval;
-
- auto printTB_result =
- printTB(m_traceback.get(), Py_None, stringIO_buffer.get());
- auto stringIO_getvalue =
- stringIO_buffer.ResolveName<PythonCallable>("getvalue");
- if (!stringIO_getvalue.IsAllocated())
- return retval;
-
- auto printTB_string = stringIO_getvalue().AsType<PythonString>();
- if (!printTB_string.IsAllocated())
- return retval;
-
- llvm::StringRef string_data(printTB_string.GetString());
- retval.assign(string_data.data(), string_data.size());
-
- return retval;
-}
-
-#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
deleted file mode 100644
index 3a88aa037776..000000000000
--- a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- PythonExceptionState.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_PYTHONEXCEPTIONSTATE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONEXCEPTIONSTATE_H
-
-#ifndef LLDB_DISABLE_PYTHON
-
-#include "PythonDataObjects.h"
-
-namespace lldb_private {
-
-class PythonExceptionState {
-public:
- explicit PythonExceptionState(bool restore_on_exit);
- ~PythonExceptionState();
-
- void Acquire(bool restore_on_exit);
-
- void Restore();
-
- void Discard();
-
- void Reset();
-
- static bool HasErrorOccurred();
-
- bool IsError() const;
-
- PythonObject GetType() const;
-
- PythonObject GetValue() const;
-
- PythonObject GetTraceback() const;
-
- std::string Format() const;
-
-private:
- std::string ReadBacktrace() const;
-
- bool m_restore_on_exit;
-
- PythonObject m_type;
- PythonObject m_value;
- PythonObject m_traceback;
-};
-}
-
-#endif
-
-#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 2d2b68ceaaa6..3eee52184142 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -16,7 +16,6 @@
#include "lldb-python.h"
#include "PythonDataObjects.h"
-#include "PythonExceptionState.h"
#include "ScriptInterpreterPythonImpl.h"
#include "lldb/API/SBFrame.h"
@@ -45,6 +44,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatAdapters.h"
#include <memory>
#include <mutex>
@@ -54,6 +54,8 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::python;
+using llvm::Expected;
// Defined in the SWIG source file
#if PY_MAJOR_VERSION >= 3
@@ -96,6 +98,8 @@ LLDBSwigPythonCreateCommandObject(const char *python_class_name,
extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
+ StructuredDataImpl *args_data,
+ std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor,
@@ -302,39 +306,26 @@ void ScriptInterpreterPython::ComputePythonDirForApple(
auto rend = llvm::sys::path::rend(path_ref);
auto framework = std::find(rbegin, rend, "LLDB.framework");
if (framework == rend) {
- ComputePythonDirForPosix(path);
+ ComputePythonDir(path);
return;
}
path.resize(framework - rend);
llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
}
-void ScriptInterpreterPython::ComputePythonDirForPosix(
+void ScriptInterpreterPython::ComputePythonDir(
llvm::SmallVectorImpl<char> &path) {
- auto style = llvm::sys::path::Style::posix;
-#if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
// Build the path by backing out of the lib dir, then building with whatever
// the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
- // x86_64).
- llvm::sys::path::remove_filename(path, style);
- llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR);
-#else
- llvm::sys::path::append(path, style,
- "python" + llvm::Twine(PY_MAJOR_VERSION) + "." +
- llvm::Twine(PY_MINOR_VERSION),
- "site-packages");
-#endif
-}
-
-void ScriptInterpreterPython::ComputePythonDirForWindows(
- llvm::SmallVectorImpl<char> &path) {
- auto style = llvm::sys::path::Style::windows;
- llvm::sys::path::remove_filename(path, style);
- llvm::sys::path::append(path, style, "lib", "site-packages");
+ // x86_64, or bin on Windows).
+ llvm::sys::path::remove_filename(path);
+ llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
+#if defined(_WIN32)
// This will be injected directly through FileSpec.GetDirectory().SetString(),
// so we need to normalize manually.
std::replace(path.begin(), path.end(), '\\', '/');
+#endif
}
FileSpec ScriptInterpreterPython::GetPythonDir() {
@@ -347,10 +338,8 @@ FileSpec ScriptInterpreterPython::GetPythonDir() {
#if defined(__APPLE__)
ComputePythonDirForApple(path);
-#elif defined(_WIN32)
- ComputePythonDirForWindows(path);
#else
- ComputePythonDirForPosix(path);
+ ComputePythonDir(path);
#endif
spec.GetDirectory().SetString(path);
return spec;
@@ -382,7 +371,7 @@ void ScriptInterpreterPython::Terminate() {}
ScriptInterpreterPythonImpl::Locker::Locker(
ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
- uint16_t on_leave, FILE *in, FILE *out, FILE *err)
+ uint16_t on_leave, FileSP in, FileSP out, FileSP err)
: ScriptInterpreterLocker(),
m_teardown_session((on_leave & TearDownSession) == TearDownSession),
m_python_interpreter(py_interpreter) {
@@ -412,8 +401,8 @@ bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() {
}
bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags,
- FILE *in, FILE *out,
- FILE *err) {
+ FileSP in, FileSP out,
+ FileSP err) {
if (!m_python_interpreter)
return false;
return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
@@ -448,9 +437,9 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(),
m_run_one_line_str_global(),
m_dictionary_name(m_debugger.GetInstanceName().AsCString()),
- m_terminal_state(), m_active_io_handler(eIOHandlerNone),
- m_session_is_active(false), m_pty_slave_is_open(false),
- m_valid_session(true), m_lock_count(0), m_command_thread_state(nullptr) {
+ m_active_io_handler(eIOHandlerNone), m_session_is_active(false),
+ m_pty_slave_is_open(false), m_valid_session(true), m_lock_count(0),
+ m_command_thread_state(nullptr) {
InitializePrivate();
m_dictionary_name.append("_dict");
@@ -535,7 +524,7 @@ def function (frame, bp_loc, internal_dict):
}
if (instructions) {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(instructions);
output_sp->Flush();
@@ -558,7 +547,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
if (!bp_options)
continue;
- auto data_up = llvm::make_unique<CommandDataPython>();
+ auto data_up = std::make_unique<CommandDataPython>();
if (!data_up)
break;
data_up->user_source.SplitIntoLines(data);
@@ -571,7 +560,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
bp_options->SetCallback(
ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
} else if (!batch_mode) {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
if (error_sp) {
error_sp->Printf("Warning: No command attached to breakpoint.\n");
error_sp->Flush();
@@ -583,7 +572,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
case eIOHandlerWatchpoint: {
WatchpointOptions *wp_options =
(WatchpointOptions *)io_handler.GetUserData();
- auto data_up = llvm::make_unique<WatchpointOptions::CommandData>();
+ auto data_up = std::make_unique<WatchpointOptions::CommandData>();
data_up->user_source.SplitIntoLines(data);
if (GenerateWatchpointCommandCallbackData(data_up->user_source,
@@ -593,7 +582,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
wp_options->SetCallback(
ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
} else if (!batch_mode) {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
if (error_sp) {
error_sp->Printf("Warning: No command attached to breakpoint.\n");
error_sp->Flush();
@@ -609,29 +598,15 @@ ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) {
return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
}
-void ScriptInterpreterPythonImpl::ResetOutputFileHandle(FILE *fh) {}
-
-void ScriptInterpreterPythonImpl::SaveTerminalState(int fd) {
- // Python mucks with the terminal state of STDIN. If we can possibly avoid
- // this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state on
- // the input file handle.
- m_terminal_state.Save(fd, false);
-}
-
-void ScriptInterpreterPythonImpl::RestoreTerminalState() {
- // Python mucks with the terminal state of STDIN. If we can possibly avoid
- // this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state on
- // the input file handle.
- m_terminal_state.Restore();
-}
-
void ScriptInterpreterPythonImpl::LeaveSession() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (log)
log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
+ // Unset the LLDB global variables.
+ PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
+ "= None; lldb.thread = None; lldb.frame = None");
+
// checking that we have a valid thread state - since we use our own
// threading and locking in some (rare) cases during cleanup Python may end
// up believing we have no thread state and PyImport_AddModule will crash if
@@ -662,45 +637,52 @@ void ScriptInterpreterPythonImpl::LeaveSession() {
m_session_is_active = false;
}
-bool ScriptInterpreterPythonImpl::SetStdHandle(File &file, const char *py_name,
- PythonFile &save_file,
+bool ScriptInterpreterPythonImpl::SetStdHandle(FileSP file_sp,
+ const char *py_name,
+ PythonObject &save_file,
const char *mode) {
- if (file.IsValid()) {
- // Flush the file before giving it to python to avoid interleaved output.
- file.Flush();
+ if (!file_sp || !*file_sp) {
+ save_file.Reset();
+ return false;
+ }
+ File &file = *file_sp;
- PythonDictionary &sys_module_dict = GetSysModuleDictionary();
+ // Flush the file before giving it to python to avoid interleaved output.
+ file.Flush();
- save_file = sys_module_dict.GetItemForKey(PythonString(py_name))
- .AsType<PythonFile>();
+ PythonDictionary &sys_module_dict = GetSysModuleDictionary();
- PythonFile new_file(file, mode);
- sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
- return true;
- } else
- save_file.Reset();
- return false;
+ auto new_file = PythonFile::FromFile(file, mode);
+ if (!new_file) {
+ llvm::consumeError(new_file.takeError());
+ return false;
+ }
+
+ save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
+
+ sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get());
+ return true;
}
bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
- FILE *in, FILE *out, FILE *err) {
+ FileSP in_sp, FileSP out_sp,
+ FileSP err_sp) {
// If we have already entered the session, without having officially 'left'
// it, then there is no need to 'enter' it again.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (m_session_is_active) {
- if (log)
- log->Printf(
- "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
- ") session is already active, returning without doing anything",
- on_entry_flags);
+ LLDB_LOGF(
+ log,
+ "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
+ ") session is already active, returning without doing anything",
+ on_entry_flags);
return false;
}
- if (log)
- log->Printf(
- "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
- ")",
- on_entry_flags);
+ LLDB_LOGF(
+ log,
+ "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")",
+ on_entry_flags);
m_session_is_active = true;
@@ -733,33 +715,29 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
PythonDictionary &sys_module_dict = GetSysModuleDictionary();
if (sys_module_dict.IsValid()) {
- File in_file(in, false);
- File out_file(out, false);
- File err_file(err, false);
-
- lldb::StreamFileSP in_sp;
- lldb::StreamFileSP out_sp;
- lldb::StreamFileSP err_sp;
- if (!in_file.IsValid() || !out_file.IsValid() || !err_file.IsValid())
- m_debugger.AdoptTopIOHandlerFilesIfInvalid(in_sp, out_sp, err_sp);
+ lldb::FileSP top_in_sp;
+ lldb::StreamFileSP top_out_sp, top_err_sp;
+ if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
+ m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
+ top_err_sp);
if (on_entry_flags & Locker::NoSTDIN) {
m_saved_stdin.Reset();
} else {
- if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r")) {
- if (in_sp)
- SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r");
+ if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r")) {
+ if (top_in_sp)
+ SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r");
}
}
- if (!SetStdHandle(out_file, "stdout", m_saved_stdout, "w")) {
- if (out_sp)
- SetStdHandle(out_sp->GetFile(), "stdout", m_saved_stdout, "w");
+ if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w")) {
+ if (top_out_sp)
+ SetStdHandle(top_out_sp->GetFileSP(), "stdout", m_saved_stdout, "w");
}
- if (!SetStdHandle(err_file, "stderr", m_saved_stderr, "w")) {
- if (err_sp)
- SetStdHandle(err_sp->GetFile(), "stderr", m_saved_stderr, "w");
+ if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w")) {
+ if (top_err_sp)
+ SetStdHandle(top_err_sp->GetFileSP(), "stderr", m_saved_stderr, "w");
}
}
@@ -769,9 +747,9 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
return true;
}
-PythonObject &ScriptInterpreterPythonImpl::GetMainModule() {
+PythonModule &ScriptInterpreterPythonImpl::GetMainModule() {
if (!m_main_module.IsValid())
- m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__"));
+ m_main_module = unwrapIgnoringErrors(PythonModule::Import("__main__"));
return m_main_module;
}
@@ -788,19 +766,16 @@ PythonDictionary &ScriptInterpreterPythonImpl::GetSessionDictionary() {
if (!main_dict.IsValid())
return m_session_dict;
- PythonObject item = main_dict.GetItemForKey(PythonString(m_dictionary_name));
- m_session_dict.Reset(PyRefType::Borrowed, item.get());
+ m_session_dict = unwrapIgnoringErrors(
+ As<PythonDictionary>(main_dict.GetItem(m_dictionary_name)));
return m_session_dict;
}
PythonDictionary &ScriptInterpreterPythonImpl::GetSysModuleDictionary() {
if (m_sys_module_dict.IsValid())
return m_sys_module_dict;
-
- PythonObject sys_module(PyRefType::Borrowed, PyImport_AddModule("sys"));
- if (sys_module.IsValid())
- m_sys_module_dict.Reset(PyRefType::Borrowed,
- PyModule_GetDict(sys_module.get()));
+ PythonModule sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
+ m_sys_module_dict = sys_module.GetDictionary();
return m_sys_module_dict;
}
@@ -867,7 +842,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
// directly down to Python.
Debugger &debugger = m_debugger;
- StreamFileSP input_file_sp;
+ FileSP input_file_sp;
StreamFileSP output_file_sp;
StreamFileSP error_file_sp;
Communication output_comm(
@@ -875,7 +850,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
bool join_read_thread = false;
if (options.GetEnableIO()) {
if (result) {
- input_file_sp = debugger.GetInputFile();
+ input_file_sp = debugger.GetInputFileSP();
// Set output to a temporary file so we can forward the results on to
// the result object
@@ -906,9 +881,9 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
::setbuf(outfile_handle, nullptr);
result->SetImmediateOutputFile(
- debugger.GetOutputFile()->GetFile().GetStream());
+ debugger.GetOutputStream().GetFileSP());
result->SetImmediateErrorFile(
- debugger.GetErrorFile()->GetFile().GetStream());
+ debugger.GetErrorStream().GetFileSP());
}
}
}
@@ -916,22 +891,26 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp,
error_file_sp);
} else {
- input_file_sp = std::make_shared<StreamFile>();
- FileSystem::Instance().Open(input_file_sp->GetFile(),
+ auto nullin = FileSystem::Instance().Open(
FileSpec(FileSystem::DEV_NULL),
File::eOpenOptionRead);
-
- output_file_sp = std::make_shared<StreamFile>();
- FileSystem::Instance().Open(output_file_sp->GetFile(),
+ auto nullout = FileSystem::Instance().Open(
FileSpec(FileSystem::DEV_NULL),
File::eOpenOptionWrite);
-
- error_file_sp = output_file_sp;
+ if (!nullin) {
+ result->AppendErrorWithFormatv("failed to open /dev/null: {0}\n",
+ llvm::fmt_consume(nullin.takeError()));
+ return false;
+ }
+ if (!nullout) {
+ result->AppendErrorWithFormatv("failed to open /dev/null: {0}\n",
+ llvm::fmt_consume(nullout.takeError()));
+ return false;
+ }
+ input_file_sp = std::move(nullin.get());
+ error_file_sp = output_file_sp = std::make_shared<StreamFile>(std::move(nullout.get()));
}
- FILE *in_file = input_file_sp->GetFile().GetStream();
- FILE *out_file = output_file_sp->GetFile().GetStream();
- FILE *err_file = error_file_sp->GetFile().GetStream();
bool success = false;
{
// WARNING! It's imperative that this RAII scope be as tight as
@@ -947,8 +926,8 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
Locker::AcquireLock | Locker::InitSession |
(options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
- Locker::FreeAcquiredLock | Locker::TearDownSession, in_file, out_file,
- err_file);
+ Locker::FreeAcquiredLock | Locker::TearDownSession, input_file_sp,
+ output_file_sp->GetFileSP(), error_file_sp->GetFileSP());
// Find the correct script interpreter dictionary in the main module.
PythonDictionary &session_dict = GetSessionDictionary();
@@ -975,9 +954,8 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
}
// Flush our output and error file handles
- ::fflush(out_file);
- if (out_file != err_file)
- ::fflush(err_file);
+ output_file_sp->Flush();
+ error_file_sp->Flush();
}
if (join_read_thread) {
@@ -1020,7 +998,7 @@ void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
// a running interpreter loop inside the already running Python interpreter
// loop, so we won't do it.
- if (!debugger.GetInputFile()->GetFile().IsValid())
+ if (!debugger.GetInputFile().IsValid())
return;
IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
@@ -1040,19 +1018,19 @@ bool ScriptInterpreterPythonImpl::Interrupt() {
long tid = state->thread_id;
PyThreadState_Swap(state);
int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
- if (log)
- log->Printf("ScriptInterpreterPythonImpl::Interrupt() sending "
- "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
- tid, num_threads);
+ LLDB_LOGF(log,
+ "ScriptInterpreterPythonImpl::Interrupt() sending "
+ "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
+ tid, num_threads);
return true;
}
}
- if (log)
- log->Printf(
- "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
- "can't interrupt");
+ LLDB_LOGF(log,
+ "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
+ "can't interrupt");
return false;
}
+
bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
void *ret_value, const ExecuteScriptOptions &options) {
@@ -1063,152 +1041,111 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
Locker::NoSTDIN,
Locker::FreeAcquiredLock | Locker::TearDownSession);
- PythonObject py_return;
- PythonObject &main_module = GetMainModule();
- PythonDictionary globals(PyRefType::Borrowed,
- PyModule_GetDict(main_module.get()));
- PythonObject py_error;
- bool ret_success = false;
- int success;
+ PythonModule &main_module = GetMainModule();
+ PythonDictionary globals = main_module.GetDictionary();
PythonDictionary locals = GetSessionDictionary();
-
- if (!locals.IsValid()) {
- locals.Reset(
- PyRefType::Owned,
- PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
- }
-
+ if (!locals.IsValid())
+ locals = unwrapIgnoringErrors(
+ As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
if (!locals.IsValid())
locals = globals;
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
-
- std::string as_string = in_string.str();
- { // scope for PythonInputReaderManager
- // PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
- py_return.Reset(PyRefType::Owned,
- PyRun_String(as_string.c_str(), Py_eval_input,
- globals.get(), locals.get()));
- if (!py_return.IsValid()) {
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
-
- py_return.Reset(PyRefType::Owned,
- PyRun_String(as_string.c_str(), Py_single_input,
- globals.get(), locals.get()));
- }
+ Expected<PythonObject> maybe_py_return =
+ runStringOneLine(in_string, globals, locals);
+
+ if (!maybe_py_return) {
+ llvm::handleAllErrors(
+ maybe_py_return.takeError(),
+ [&](PythonException &E) {
+ E.Restore();
+ if (options.GetMaskoutErrors()) {
+ if (E.Matches(PyExc_SyntaxError)) {
+ PyErr_Print();
+ }
+ PyErr_Clear();
+ }
+ },
+ [](const llvm::ErrorInfoBase &E) {});
+ return false;
}
- if (py_return.IsValid()) {
- switch (return_type) {
- case eScriptReturnTypeCharPtr: // "char *"
- {
- const char format[3] = "s#";
- success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
- break;
- }
- case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
- // Py_None
- {
- const char format[3] = "z";
- success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
- break;
- }
- case eScriptReturnTypeBool: {
- const char format[2] = "b";
- success = PyArg_Parse(py_return.get(), format, (bool *)ret_value);
- break;
- }
- case eScriptReturnTypeShortInt: {
- const char format[2] = "h";
- success = PyArg_Parse(py_return.get(), format, (short *)ret_value);
- break;
- }
- case eScriptReturnTypeShortIntUnsigned: {
- const char format[2] = "H";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
- break;
- }
- case eScriptReturnTypeInt: {
- const char format[2] = "i";
- success = PyArg_Parse(py_return.get(), format, (int *)ret_value);
- break;
- }
- case eScriptReturnTypeIntUnsigned: {
- const char format[2] = "I";
- success = PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
- break;
- }
- case eScriptReturnTypeLongInt: {
- const char format[2] = "l";
- success = PyArg_Parse(py_return.get(), format, (long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongIntUnsigned: {
- const char format[2] = "k";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongLong: {
- const char format[2] = "L";
- success = PyArg_Parse(py_return.get(), format, (long long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongLongUnsigned: {
- const char format[2] = "K";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned long long *)ret_value);
- break;
- }
- case eScriptReturnTypeFloat: {
- const char format[2] = "f";
- success = PyArg_Parse(py_return.get(), format, (float *)ret_value);
- break;
- }
- case eScriptReturnTypeDouble: {
- const char format[2] = "d";
- success = PyArg_Parse(py_return.get(), format, (double *)ret_value);
- break;
- }
- case eScriptReturnTypeChar: {
- const char format[2] = "c";
- success = PyArg_Parse(py_return.get(), format, (char *)ret_value);
- break;
- }
- case eScriptReturnTypeOpaqueObject: {
- success = true;
- PyObject *saved_value = py_return.get();
- Py_XINCREF(saved_value);
- *((PyObject **)ret_value) = saved_value;
- break;
- }
- }
+ PythonObject py_return = std::move(maybe_py_return.get());
+ assert(py_return.IsValid());
- ret_success = success;
+ switch (return_type) {
+ case eScriptReturnTypeCharPtr: // "char *"
+ {
+ const char format[3] = "s#";
+ return PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ }
+ case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
+ // Py_None
+ {
+ const char format[3] = "z";
+ return PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ }
+ case eScriptReturnTypeBool: {
+ const char format[2] = "b";
+ return PyArg_Parse(py_return.get(), format, (bool *)ret_value);
+ }
+ case eScriptReturnTypeShortInt: {
+ const char format[2] = "h";
+ return PyArg_Parse(py_return.get(), format, (short *)ret_value);
+ }
+ case eScriptReturnTypeShortIntUnsigned: {
+ const char format[2] = "H";
+ return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
+ }
+ case eScriptReturnTypeInt: {
+ const char format[2] = "i";
+ return PyArg_Parse(py_return.get(), format, (int *)ret_value);
+ }
+ case eScriptReturnTypeIntUnsigned: {
+ const char format[2] = "I";
+ return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
+ }
+ case eScriptReturnTypeLongInt: {
+ const char format[2] = "l";
+ return PyArg_Parse(py_return.get(), format, (long *)ret_value);
+ }
+ case eScriptReturnTypeLongIntUnsigned: {
+ const char format[2] = "k";
+ return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
+ }
+ case eScriptReturnTypeLongLong: {
+ const char format[2] = "L";
+ return PyArg_Parse(py_return.get(), format, (long long *)ret_value);
+ }
+ case eScriptReturnTypeLongLongUnsigned: {
+ const char format[2] = "K";
+ return PyArg_Parse(py_return.get(), format,
+ (unsigned long long *)ret_value);
+ }
+ case eScriptReturnTypeFloat: {
+ const char format[2] = "f";
+ return PyArg_Parse(py_return.get(), format, (float *)ret_value);
+ }
+ case eScriptReturnTypeDouble: {
+ const char format[2] = "d";
+ return PyArg_Parse(py_return.get(), format, (double *)ret_value);
+ }
+ case eScriptReturnTypeChar: {
+ const char format[2] = "c";
+ return PyArg_Parse(py_return.get(), format, (char *)ret_value);
+ }
+ case eScriptReturnTypeOpaqueObject: {
+ *((PyObject **)ret_value) = py_return.release();
+ return true;
}
-
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid()) {
- ret_success = false;
- if (options.GetMaskoutErrors()) {
- if (PyErr_GivenExceptionMatches(py_error.get(), PyExc_SyntaxError))
- PyErr_Print();
- PyErr_Clear();
- }
}
-
- return ret_success;
}
Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
const char *in_string, const ExecuteScriptOptions &options) {
- Status error;
+
+ if (in_string == nullptr)
+ return Status();
Locker locker(this,
Locker::AcquireLock | Locker::InitSession |
@@ -1216,52 +1153,32 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
Locker::NoSTDIN,
Locker::FreeAcquiredLock | Locker::TearDownSession);
- PythonObject return_value;
- PythonObject &main_module = GetMainModule();
- PythonDictionary globals(PyRefType::Borrowed,
- PyModule_GetDict(main_module.get()));
- PythonObject py_error;
+ PythonModule &main_module = GetMainModule();
+ PythonDictionary globals = main_module.GetDictionary();
PythonDictionary locals = GetSessionDictionary();
-
if (!locals.IsValid())
- locals.Reset(
- PyRefType::Owned,
- PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
-
+ locals = unwrapIgnoringErrors(
+ As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
if (!locals.IsValid())
locals = globals;
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
+ Expected<PythonObject> return_value =
+ runStringMultiLine(in_string, globals, locals);
- if (in_string != nullptr) {
- PythonObject code_object;
- code_object.Reset(PyRefType::Owned,
- Py_CompileString(in_string, "temp.py", Py_file_input));
-
- if (code_object.IsValid()) {
-// In Python 2.x, PyEval_EvalCode takes a PyCodeObject, but in Python 3.x, it
-// takes a PyObject. They are convertible (hence the function
-// PyCode_Check(PyObject*), so we have to do the cast for Python 2.x
-#if PY_MAJOR_VERSION >= 3
- PyObject *py_code_obj = code_object.get();
-#else
- PyCodeObject *py_code_obj =
- reinterpret_cast<PyCodeObject *>(code_object.get());
-#endif
- return_value.Reset(
- PyRefType::Owned,
- PyEval_EvalCode(py_code_obj, globals.get(), locals.get()));
- }
+ if (!return_value) {
+ llvm::Error error =
+ llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
+ llvm::Error error = llvm::createStringError(
+ llvm::inconvertibleErrorCode(), E.ReadBacktrace());
+ if (!options.GetMaskoutErrors())
+ E.Restore();
+ return error;
+ });
+ return Status(std::move(error));
}
- PythonExceptionState exception_state(!options.GetMaskoutErrors());
- if (exception_state.IsError())
- error.SetErrorString(exception_state.Format().c_str());
-
- return error;
+ return Status();
}
void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
@@ -1308,7 +1225,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
// Set a Python one-liner as the callback for the breakpoint.
Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
BreakpointOptions *bp_options, const char *command_body_text) {
- auto data_up = llvm::make_unique<CommandDataPython>();
+ auto data_up = std::make_unique<CommandDataPython>();
// Split the command_body_text into lines, and pass that to
// GenerateBreakpointCommandCallbackData. That will wrap the body in an
@@ -1331,7 +1248,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
// Set a Python one-liner as the callback for the watchpoint.
void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback(
WatchpointOptions *wp_options, const char *oneliner) {
- auto data_up = llvm::make_unique<WatchpointOptions::CommandData>();
+ auto data_up = std::make_unique<WatchpointOptions::CommandData>();
// It's necessary to set both user_source and script_source to the oneliner.
// The former is used to generate callback description (as in watchpoint
@@ -1853,12 +1770,14 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
}
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
- const char *class_name, lldb::ThreadPlanSP thread_plan_sp) {
+ const char *class_name, StructuredDataImpl *args_data,
+ std::string &error_str,
+ lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
if (!thread_plan_sp.get())
- return StructuredData::ObjectSP();
+ return {};
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
@@ -1866,17 +1785,18 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
if (!script_interpreter)
- return StructuredData::ObjectSP();
+ return {};
void *ret_val;
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-
ret_val = LLDBSwigPythonCreateScriptedThreadPlan(
class_name, python_interpreter->m_dictionary_name.c_str(),
- thread_plan_sp);
+ args_data, error_str, thread_plan_sp);
+ if (!ret_val)
+ return {};
}
return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
@@ -2052,15 +1972,22 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings(
if (!generic)
return StructuredData::DictionarySP();
- PythonObject reply_pyobj;
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
TargetSP target_sp(target->shared_from_this());
- reply_pyobj.Reset(PyRefType::Owned,
- (PyObject *)LLDBSWIGPython_GetDynamicSetting(
- generic->GetValue(), setting_name, target_sp));
- PythonDictionary py_dict(PyRefType::Borrowed, reply_pyobj.get());
+ auto setting = (PyObject *)LLDBSWIGPython_GetDynamicSetting(
+ generic->GetValue(), setting_name, target_sp);
+
+ if (!setting)
+ return StructuredData::DictionarySP();
+
+ PythonDictionary py_dict =
+ unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting)));
+
+ if (!py_dict)
+ return StructuredData::DictionarySP();
+
return py_dict.CreateStructuredDictionary();
}
@@ -2230,18 +2157,6 @@ bool ScriptInterpreterPythonImpl::GetScriptedSummary(
return ret_val;
}
-void ScriptInterpreterPythonImpl::Clear() {
- // Release any global variables that might have strong references to
- // LLDB objects when clearing the python script interpreter.
- Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock);
-
- // This may be called as part of Py_Finalize. In that case the modules are
- // destroyed in random order and we can't guarantee that we can access these.
- if (Py_IsInitialized())
- PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
- "= None; lldb.thread = None; lldb.frame = None");
-}
-
bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index 24941ec77452..33ae308041b2 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -48,8 +48,7 @@ public:
protected:
static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path);
- static void ComputePythonDirForPosix(llvm::SmallVectorImpl<char> &path);
- static void ComputePythonDirForWindows(llvm::SmallVectorImpl<char> &path);
+ static void ComputePythonDir(llvm::SmallVectorImpl<char> &path);
};
} // namespace lldb_private
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index a9993c4068a2..929567e579d8 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -78,6 +78,8 @@ public:
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ StructuredDataImpl *args_data,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
@@ -188,8 +190,6 @@ public:
const TypeSummaryOptions &options,
std::string &retval) override;
- void Clear() override;
-
bool GetDocumentationForItem(const char *item, std::string &dest) override;
bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
@@ -256,8 +256,6 @@ public:
void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
const char *oneliner) override;
- void ResetOutputFileHandle(FILE *new_fh) override;
-
const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
PyThreadState *GetThreadState() { return m_command_thread_state; }
@@ -296,17 +294,19 @@ public:
TearDownSession = 0x0004
};
- Locker(ScriptInterpreterPythonImpl *py_interpreter = nullptr,
+ Locker(ScriptInterpreterPythonImpl *py_interpreter,
uint16_t on_entry = AcquireLock | InitSession,
- uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
- FILE *out = nullptr, FILE *err = nullptr);
+ uint16_t on_leave = FreeLock | TearDownSession,
+ lldb::FileSP in = nullptr, lldb::FileSP out = nullptr,
+ lldb::FileSP err = nullptr);
~Locker() override;
private:
bool DoAcquireLock();
- bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
+ bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in,
+ lldb::FileSP out, lldb::FileSP err);
bool DoFreeLock();
@@ -314,7 +314,6 @@ public:
bool m_teardown_session;
ScriptInterpreterPythonImpl *m_python_interpreter;
- // FILE* m_tmp_fh;
PyGILState_STATE m_GILState;
};
@@ -343,14 +342,11 @@ public:
static void AddToSysPath(AddLocation location, std::string path);
- bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
+ bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out,
+ lldb::FileSP err);
void LeaveSession();
- void SaveTerminalState(int fd);
-
- void RestoreTerminalState();
-
uint32_t IsExecutingPython() const { return m_lock_count > 0; }
uint32_t IncrementLockCount() { return ++m_lock_count; }
@@ -367,27 +363,26 @@ public:
eIOHandlerWatchpoint
};
- PythonObject &GetMainModule();
+ python::PythonModule &GetMainModule();
- PythonDictionary &GetSessionDictionary();
+ python::PythonDictionary &GetSessionDictionary();
- PythonDictionary &GetSysModuleDictionary();
+ python::PythonDictionary &GetSysModuleDictionary();
bool GetEmbeddedInterpreterModuleObjects();
- bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
- const char *mode);
-
- PythonFile m_saved_stdin;
- PythonFile m_saved_stdout;
- PythonFile m_saved_stderr;
- PythonObject m_main_module;
- PythonDictionary m_session_dict;
- PythonDictionary m_sys_module_dict;
- PythonObject m_run_one_line_function;
- PythonObject m_run_one_line_str_global;
+ bool SetStdHandle(lldb::FileSP file, const char *py_name,
+ python::PythonObject &save_file, const char *mode);
+
+ python::PythonObject m_saved_stdin;
+ python::PythonObject m_saved_stdout;
+ python::PythonObject m_saved_stderr;
+ python::PythonModule m_main_module;
+ python::PythonDictionary m_session_dict;
+ python::PythonDictionary m_sys_module_dict;
+ python::PythonObject m_run_one_line_function;
+ python::PythonObject m_run_one_line_str_global;
std::string m_dictionary_name;
- TerminalState m_terminal_state;
ActiveIOHandler m_active_io_handler;
bool m_session_is_active;
bool m_pty_slave_is_open;
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index 81a27125c036..c6b234baa8c8 100644
--- a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -104,30 +104,13 @@ void SetGlobalEnableOptions(const DebuggerSP &debugger_sp,
/// Code to handle the StructuredDataDarwinLog settings
-static constexpr PropertyDefinition g_properties[] = {
- {
- "enable-on-startup", // name
- OptionValue::eTypeBoolean, // type
- true, // global
- false, // default uint value
- nullptr, // default cstring value
- {}, // enum values
- "Enable Darwin os_log collection when debugged process is launched "
- "or attached." // description
- },
- {
- "auto-enable-options", // name
- OptionValue::eTypeString, // type
- true, // global
- 0, // default uint value
- "", // default cstring value
- {}, // enum values
- "Specify the options to 'plugin structured-data darwin-log enable' "
- "that should be applied when automatically enabling logging on "
- "startup/attach." // description
- }};
-
-enum { ePropertyEnableOnStartup = 0, ePropertyAutoEnableOptions = 1 };
+#define LLDB_PROPERTIES_darwinlog
+#include "StructuredDataDarwinLogProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_darwinlog
+#include "StructuredDataDarwinLogPropertiesEnum.inc"
+};
class StructuredDataDarwinLogProperties : public Properties {
public:
@@ -138,7 +121,7 @@ public:
StructuredDataDarwinLogProperties() : Properties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_darwinlog_properties);
}
~StructuredDataDarwinLogProperties() override {}
@@ -146,13 +129,13 @@ public:
bool GetEnableOnStartup() const {
const uint32_t idx = ePropertyEnableOnStartup;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_darwinlog_properties[idx].default_uint_value != 0);
}
llvm::StringRef GetAutoEnableOptions() const {
const uint32_t idx = ePropertyAutoEnableOptions;
return m_collection_sp->GetPropertyAtIndexAsString(
- nullptr, idx, g_properties[idx].default_cstr_value);
+ nullptr, idx, g_darwinlog_properties[idx].default_cstr_value);
}
const char *GetLoggingModuleName() const { return "libsystem_trace.dylib"; }
@@ -305,11 +288,8 @@ private:
// Instantiate the regex so we can report any errors.
auto regex = RegularExpression(op_arg);
- if (!regex.IsValid()) {
- char error_text[256];
- error_text[0] = '\0';
- regex.GetErrorAsCString(error_text, sizeof(error_text));
- error.SetErrorString(error_text);
+ if (llvm::Error err = regex.GetError()) {
+ error.SetErrorString(llvm::toString(std::move(err)));
return FilterRuleSP();
}
@@ -807,15 +787,10 @@ protected:
// Now check if we have a running process. If so, we should instruct the
// process monitor to enable/disable DarwinLog support now.
- Target *target = GetSelectedOrDummyTarget();
- if (!target) {
- // No target, so there is nothing more to do right now.
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
- }
+ Target &target = GetSelectedOrDummyTarget();
// Grab the active process.
- auto process_sp = target->GetProcessSP();
+ auto process_sp = target.GetProcessSP();
if (!process_sp) {
// No active process, so there is nothing more to do right now.
result.SetStatus(eReturnStatusSuccessFinishNoResult);
@@ -897,9 +872,9 @@ protected:
// Figure out if we've got a process. If so, we can tell if DarwinLog is
// available for that process.
- Target *target = GetSelectedOrDummyTarget();
- auto process_sp = target ? target->GetProcessSP() : ProcessSP();
- if (!target || !process_sp) {
+ Target &target = GetSelectedOrDummyTarget();
+ auto process_sp = target.GetProcessSP();
+ if (!process_sp) {
stream.PutCString("Availability: unknown (requires process)\n");
stream.PutCString("Enabled: not applicable "
"(requires process)\n");
@@ -1119,26 +1094,26 @@ void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
object_sp->Dump(json_stream);
else
json_stream.PutCString("<null>");
- log->Printf("StructuredDataDarwinLog::%s() called with json: %s",
- __FUNCTION__, json_stream.GetData());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called with json: %s",
+ __FUNCTION__, json_stream.GetData());
}
// Ignore empty structured data.
if (!object_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() StructuredData object "
- "is null",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() StructuredData object "
+ "is null",
+ __FUNCTION__);
return;
}
// Ignore any data that isn't for us.
if (type_name != GetDarwinLogTypeName()) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() StructuredData type "
- "expected to be %s but was %s, ignoring",
- __FUNCTION__, GetDarwinLogTypeName().AsCString(),
- type_name.AsCString());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() StructuredData type "
+ "expected to be %s but was %s, ignoring",
+ __FUNCTION__, GetDarwinLogTypeName().AsCString(),
+ type_name.AsCString());
return;
}
@@ -1148,9 +1123,8 @@ void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
DebuggerSP debugger_sp = process.GetTarget().GetDebugger().shared_from_this();
auto options_sp = GetGlobalEnableOptions(debugger_sp);
if (options_sp && options_sp->GetBroadcastEvents()) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() broadcasting event",
- __FUNCTION__);
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() broadcasting event",
+ __FUNCTION__);
process.BroadcastStructuredData(object_sp, shared_from_this());
}
@@ -1263,19 +1237,18 @@ void StructuredDataDarwinLog::SetEnabled(bool enabled) {
void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
ModuleList &module_list) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s called (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s called (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
// Check if we should enable the darwin log support on startup/attach.
if (!GetGlobalProperties()->GetEnableOnStartup() &&
!s_is_explicitly_enabled) {
// We're neither auto-enabled or explicitly enabled, so we shouldn't try to
// enable here.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s not applicable, we're not "
- "enabled (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s not applicable, we're not "
+ "enabled (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
return;
}
@@ -1283,10 +1256,10 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
{
std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
if (m_added_breakpoint) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s process uid %u's "
- "post-libtrace-init breakpoint is already set",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s process uid %u's "
+ "post-libtrace-init breakpoint is already set",
+ __FUNCTION__, process.GetUniqueID());
return;
}
}
@@ -1298,11 +1271,11 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
GetGlobalProperties()->GetLoggingModuleName();
if (!logging_module_cstr || (logging_module_cstr[0] == 0)) {
// We need this. Bail.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s no logging module name "
- "specified, we don't know where to set a breakpoint "
- "(process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s no logging module name "
+ "specified, we don't know where to set a breakpoint "
+ "(process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
return;
}
@@ -1324,23 +1297,23 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
}
if (!found_logging_support_module) {
- if (log)
- log->Printf("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());
+ LLDB_LOGF(log,
+ "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());
return;
}
// Time to enqueue the breakpoint so we can wait for logging support to be
// initialized before we try to tap the libtrace stream.
AddInitCompletionHook(process);
- if (log)
- log->Printf("StructuredDataDarwinLog::%s post-init hook breakpoint "
- "set for logging module %s (process uid %u)",
- __FUNCTION__, logging_module_name.AsCString(),
- process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s post-init hook breakpoint "
+ "set for logging module %s (process uid %u)",
+ __FUNCTION__, logging_module_name.AsCString(),
+ 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
@@ -1519,38 +1492,36 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
// we can execute our logic to enable the logging support.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);
// Get the current thread.
if (!context) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: no context, "
- "ignoring",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: no context, "
+ "ignoring",
+ __FUNCTION__);
return false;
}
// Get the plugin from the process.
auto process_sp = context->exe_ctx_ref.GetProcessSP();
if (!process_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: invalid "
- "process in context, ignoring",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: invalid "
+ "process in context, ignoring",
+ __FUNCTION__);
return false;
}
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() call is for process uid %d",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %d",
+ __FUNCTION__, process_sp->GetUniqueID());
auto plugin_sp = process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
if (!plugin_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: no plugin for "
- "feature %s in process uid %u",
- __FUNCTION__, GetDarwinLogTypeName().AsCString(),
- process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: no plugin for "
+ "feature %s in process uid %u",
+ __FUNCTION__, GetDarwinLogTypeName().AsCString(),
+ process_sp->GetUniqueID());
return false;
}
@@ -1561,51 +1532,51 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
std::weak_ptr<StructuredDataPlugin> plugin_wp(plugin_sp);
ThreadPlanCallOnFunctionExit::Callback callback =
[plugin_wp, &called_enable_method, log, process_uid]() {
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "called (process uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "called (process uid %u)",
+ process_uid);
auto strong_plugin_sp = plugin_wp.lock();
if (!strong_plugin_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "plugin no longer exists, ignoring (process "
- "uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "plugin no longer exists, ignoring (process "
+ "uid %u)",
+ process_uid);
return;
}
// Make sure we only call it once, just in case the thread plan hits
// the breakpoint twice.
if (!called_enable_method) {
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "calling EnableNow() (process uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "calling EnableNow() (process uid %u)",
+ process_uid);
static_cast<StructuredDataDarwinLog *>(strong_plugin_sp.get())
->EnableNow();
called_enable_method = true;
} else {
// Our breakpoint was hit more than once. Unexpected but no harm
// done. Log it.
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "skipping EnableNow(), already called by "
- "callback [we hit this more than once] "
- "(process uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "skipping EnableNow(), already called by "
+ "callback [we hit this more than once] "
+ "(process uid %u)",
+ process_uid);
}
};
// Grab the current thread.
auto thread_sp = context->exe_ctx_ref.GetThreadSP();
if (!thread_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to "
- "retrieve the current thread from the execution "
- "context, nowhere to run the thread plan (process uid "
- "%u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to "
+ "retrieve the current thread from the execution "
+ "context, nowhere to run the thread plan (process uid "
+ "%u)",
+ __FUNCTION__, process_sp->GetUniqueID());
return false;
}
@@ -1614,10 +1585,10 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
ThreadPlanSP(new ThreadPlanCallOnFunctionExit(*thread_sp, callback));
const bool abort_other_plans = false;
thread_sp->QueueThreadPlan(thread_plan_sp, abort_other_plans);
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() queuing thread plan on "
- "trace library init method entry (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() queuing thread plan on "
+ "trace library init method entry (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
// We return false here to indicate that it isn't a public stop.
return false;
@@ -1625,18 +1596,17 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() called (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
// Make sure we haven't already done this.
{
std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
if (m_added_breakpoint) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() ignoring request, "
- "breakpoint already set (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() ignoring request, "
+ "breakpoint already set (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
return;
}
@@ -1669,22 +1639,22 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
eLanguageTypeC, offset, skip_prologue, internal, hardware);
if (!breakpoint_sp) {
// Huh? Bail here.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() failed to set "
- "breakpoint in module %s, function %s (process uid %u)",
- __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
- func_name, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() failed to set "
+ "breakpoint in module %s, function %s (process uid %u)",
+ __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
+ func_name, process.GetUniqueID());
return;
}
// Set our callback.
breakpoint_sp->SetCallback(InitCompletionHookCallback, nullptr);
m_breakpoint_id = breakpoint_sp->GetID();
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() breakpoint set in module %s,"
- "function %s (process uid %u)",
- __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
- func_name, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() breakpoint set in module %s,"
+ "function %s (process uid %u)",
+ __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
+ func_name, process.GetUniqueID());
}
void StructuredDataDarwinLog::DumpTimestamp(Stream &stream,
@@ -1825,22 +1795,20 @@ size_t StructuredDataDarwinLog::HandleDisplayOfEvent(
void StructuredDataDarwinLog::EnableNow() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);
// Run the enable command.
auto process_sp = GetProcess();
if (!process_sp) {
// Nothing to do.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to get "
- "valid process, skipping",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to get "
+ "valid process, skipping",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() call is for process uid %u",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %u",
+ __FUNCTION__, process_sp->GetUniqueID());
// If we have configuration data, we can directly enable it now. Otherwise,
// we need to run through the command interpreter to parse the auto-run
@@ -1849,10 +1817,10 @@ void StructuredDataDarwinLog::EnableNow() {
DebuggerSP debugger_sp =
process_sp->GetTarget().GetDebugger().shared_from_this();
if (!debugger_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to get "
- "debugger shared pointer, skipping (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to get "
+ "debugger shared pointer, skipping (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
return;
}
@@ -1864,13 +1832,15 @@ void StructuredDataDarwinLog::EnableNow() {
const bool success = RunEnableCommand(interpreter);
if (log) {
if (success)
- log->Printf("StructuredDataDarwinLog::%s() ran enable command "
- "successfully for (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() ran enable command "
+ "successfully for (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
else
- log->Printf("StructuredDataDarwinLog::%s() error: running "
- "enable command failed (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() error: running "
+ "enable command failed (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
}
// Report failures to the debugger error stream.
auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
@@ -1886,11 +1856,11 @@ void StructuredDataDarwinLog::EnableNow() {
// specified options.
auto config_sp = options_sp->BuildConfigurationData(true);
if (!config_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to "
- "build configuration data for enable options, skipping "
- "(process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to "
+ "build configuration data for enable options, skipping "
+ "(process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
return;
}
@@ -1901,11 +1871,11 @@ void StructuredDataDarwinLog::EnableNow() {
// Report results.
if (!error.Success()) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() "
- "ConfigureStructuredData() call failed "
- "(process uid %u): %s",
- __FUNCTION__, process_sp->GetUniqueID(), error.AsCString());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() "
+ "ConfigureStructuredData() call failed "
+ "(process uid %u): %s",
+ __FUNCTION__, process_sp->GetUniqueID(), error.AsCString());
auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
if (error_stream_sp) {
error_stream_sp->Printf("failed to configure DarwinLog "
@@ -1916,9 +1886,9 @@ void StructuredDataDarwinLog::EnableNow() {
m_is_enabled = false;
} else {
m_is_enabled = true;
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() success via direct "
- "configuration (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() success via direct "
+ "configuration (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
}
}
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td
new file mode 100644
index 000000000000..5c22158542f9
--- /dev/null
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td
@@ -0,0 +1,12 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "darwinlog" in {
+ def EnableOnStartup: Property<"enable-on-startup", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Enable Darwin os_log collection when debugged process is launched or attached.">;
+ def AutoEnableOptions: Property<"auto-enable-options", "String">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Specify the options to 'plugin structured-data darwin-log enable' that should be applied when automatically enabling logging on startup/attach.">;
+}
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index d4258274a38c..f84cf0c5368d 100644
--- a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -15,7 +15,6 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Utility/Log.h"
@@ -126,8 +125,8 @@ SymbolFileBreakpad::LineIterator::operator++() {
llvm::iterator_range<SymbolFileBreakpad::LineIterator>
SymbolFileBreakpad::lines(Record::Kind section_type) {
- return llvm::make_range(LineIterator(*m_obj_file, section_type),
- LineIterator(*m_obj_file));
+ return llvm::make_range(LineIterator(*m_objfile_sp, section_type),
+ LineIterator(*m_objfile_sp));
}
namespace {
@@ -179,15 +178,13 @@ ConstString SymbolFileBreakpad::GetPluginNameStatic() {
}
uint32_t SymbolFileBreakpad::CalculateAbilities() {
- if (!m_obj_file)
- return 0;
- if (m_obj_file->GetPluginName() != ObjectFileBreakpad::GetPluginNameStatic())
+ if (!m_objfile_sp || !llvm::isa<ObjectFileBreakpad>(*m_objfile_sp))
return 0;
return CompileUnits | Functions | LineTables;
}
-uint32_t SymbolFileBreakpad::GetNumCompileUnits() {
+uint32_t SymbolFileBreakpad::CalculateNumCompileUnits() {
ParseCUData();
return m_cu_data->GetSize();
}
@@ -204,7 +201,8 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
// The FileSpec of the compile unit will be the file corresponding to the
// first LINE record.
- LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::Func, data.bookmark),
+ End(*m_objfile_sp);
assert(Record::classify(*It) == Record::Func);
++It; // Skip FUNC record.
if (It != End) {
@@ -213,12 +211,12 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
spec = (*m_files)[record->FileNum];
}
- auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(),
+ auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(),
/*user_data*/ nullptr, spec, index,
eLanguageTypeUnknown,
/*is_optimized*/ eLazyBoolNo);
- GetSymbolVendor().SetCompileUnitAtIndex(index, cu_sp);
+ SetCompileUnitAtIndex(index, cu_sp);
return cu_sp;
}
@@ -228,6 +226,7 @@ size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
if (!data.line_table_up)
@@ -239,6 +238,7 @@ bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
bool SymbolFileBreakpad::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
if (!data.support_files)
ParseLineTableAndSupportFiles(comp_unit, data);
@@ -251,6 +251,7 @@ uint32_t
SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry)))
return 0;
@@ -260,7 +261,7 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
if (idx == UINT32_MAX)
return 0;
- sc.comp_unit = GetSymbolVendor().GetCompileUnitAtIndex(idx).get();
+ sc.comp_unit = GetCompileUnitAtIndex(idx).get();
SymbolContextItem result = eSymbolContextCompUnit;
if (resolve_scope & eSymbolContextLineEntry) {
if (sc.comp_unit->GetLineTable()->FindLineEntryByAddress(so_addr,
@@ -275,57 +276,43 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
uint32_t SymbolFileBreakpad::ResolveSymbolContext(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!(resolve_scope & eSymbolContextCompUnit))
return 0;
uint32_t old_size = sc_list.GetSize();
for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) {
- CompileUnit &cu = *GetSymbolVendor().GetCompileUnitAtIndex(i);
+ CompileUnit &cu = *GetCompileUnitAtIndex(i);
cu.ResolveSymbolContext(file_spec, line, check_inlines,
/*exact*/ false, resolve_scope, sc_list);
}
return sc_list.GetSize() - old_size;
}
-uint32_t SymbolFileBreakpad::FindFunctions(
+void SymbolFileBreakpad::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
// TODO
- if (!append)
- sc_list.Clear();
- return sc_list.GetSize();
}
-uint32_t SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
// TODO
- if (!append)
- sc_list.Clear();
- return sc_list.GetSize();
}
-uint32_t SymbolFileBreakpad::FindTypes(
+void SymbolFileBreakpad::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- if (!append)
- types.Clear();
- return types.GetSize();
-}
+ uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {}
-size_t
-SymbolFileBreakpad::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- if (!append)
- types.Clear();
- return types.GetSize();
-}
+void SymbolFileBreakpad::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {}
void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
- Module &module = *m_obj_file->GetModule();
+ Module &module = *m_objfile_sp->GetModule();
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS) {
LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping "
@@ -347,8 +334,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
return;
}
symbols.try_emplace(
- address, /*symID*/ 0, Mangled(name, /*is_mangled*/ false),
- eSymbolTypeCode, /*is_global*/ true, /*is_debug*/ false,
+ address, /*symID*/ 0, Mangled(name), eSymbolTypeCode,
+ /*is_global*/ true, /*is_debug*/ false,
/*is_trampoline*/ false, /*is_artificial*/ false,
AddressRange(section_sp, address - section_sp->GetFileAddress(),
size.getValueOr(0)),
@@ -372,6 +359,20 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
symtab.CalculateSymbolSizes();
}
+llvm::Expected<lldb::addr_t>
+SymbolFileBreakpad::GetParameterStackSize(Symbol &symbol) {
+ ParseUnwindData();
+ if (auto *entry = m_unwind_data->win.FindEntryThatContains(
+ symbol.GetAddress().GetFileAddress())) {
+ auto record = StackWinRecord::parse(
+ *LineIterator(*m_objfile_sp, Record::StackWin, entry->data));
+ assert(record.hasValue());
+ return record->ParameterSize;
+ }
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Parameter size unknown.");
+}
+
static llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>>
GetRule(llvm::StringRef &unwind_rules) {
// Unwind rules are of the form
@@ -418,7 +419,17 @@ ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver,
return ResolveRegister(resolver, name);
}
-bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
+llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) {
+ ArchSpec arch = m_objfile_sp->GetArchitecture();
+ StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
+ arch.GetByteOrder());
+ ToDWARF(node, dwarf);
+ uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
+ std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
+ return {saved, dwarf.GetSize()};
+}
+
+bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
const RegisterInfoResolver &resolver,
UnwindPlan::Row &row) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
@@ -427,7 +438,7 @@ bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
while (auto rule = GetRule(unwind_rules)) {
node_alloc.Reset();
llvm::StringRef lhs = rule->first;
- postfix::Node *rhs = postfix::Parse(rule->second, node_alloc);
+ postfix::Node *rhs = postfix::ParseOneExpression(rule->second, node_alloc);
if (!rhs) {
LLDB_LOG(log, "Could not parse `{0}` as unwind rhs.", rule->second);
return false;
@@ -451,18 +462,12 @@ bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
return false;
}
- ArchSpec arch = m_obj_file->GetArchitecture();
- StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
- arch.GetByteOrder());
- ToDWARF(*rhs, dwarf);
- uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
- std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
-
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*rhs);
if (lhs == ".cfa") {
- row.GetCFAValue().SetIsDWARFExpression(saved, dwarf.GetSize());
+ row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
} else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) {
UnwindPlan::Row::RegisterLocation loc;
- loc.SetIsDWARFExpression(saved, dwarf.GetSize());
+ loc.SetIsDWARFExpression(saved.data(), saved.size());
row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
} else
LLDB_LOG(log, "Invalid register `{0}` in unwind rule.", lhs);
@@ -478,31 +483,40 @@ UnwindPlanSP
SymbolFileBreakpad::GetUnwindPlan(const Address &address,
const RegisterInfoResolver &resolver) {
ParseUnwindData();
- const UnwindMap::Entry *entry =
- m_unwind_data->FindEntryThatContains(address.GetFileAddress());
- if (!entry)
- return nullptr;
+ if (auto *entry =
+ m_unwind_data->cfi.FindEntryThatContains(address.GetFileAddress()))
+ return ParseCFIUnwindPlan(entry->data, resolver);
+ if (auto *entry =
+ m_unwind_data->win.FindEntryThatContains(address.GetFileAddress()))
+ return ParseWinUnwindPlan(entry->data, resolver);
+ return nullptr;
+}
+UnwindPlanSP
+SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver) {
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS)
return nullptr;
- LineIterator It(*m_obj_file, Record::StackCFI, entry->data), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::StackCFI, bookmark),
+ End(*m_objfile_sp);
llvm::Optional<StackCFIRecord> init_record = StackCFIRecord::parse(*It);
- assert(init_record.hasValue());
- assert(init_record->Size.hasValue());
+ assert(init_record.hasValue() && init_record->Size.hasValue() &&
+ "Record already parsed successfully in ParseUnwindData!");
auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
plan_sp->SetSourceName("breakpad STACK CFI");
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
plan_sp->SetPlanValidAddressRange(
AddressRange(base + init_record->Address, *init_record->Size,
- m_obj_file->GetModule()->GetSectionList()));
+ m_objfile_sp->GetModule()->GetSectionList()));
auto row_sp = std::make_shared<UnwindPlan::Row>();
row_sp->SetOffset(0);
- if (!ParseUnwindRow(init_record->UnwindRules, resolver, *row_sp))
+ if (!ParseCFIUnwindRow(init_record->UnwindRules, resolver, *row_sp))
return nullptr;
plan_sp->AppendRow(row_sp);
for (++It; It != End; ++It) {
@@ -514,19 +528,107 @@ SymbolFileBreakpad::GetUnwindPlan(const Address &address,
row_sp = std::make_shared<UnwindPlan::Row>(*row_sp);
row_sp->SetOffset(record->Address - init_record->Address);
- if (!ParseUnwindRow(record->UnwindRules, resolver, *row_sp))
+ if (!ParseCFIUnwindRow(record->UnwindRules, resolver, *row_sp))
return nullptr;
plan_sp->AppendRow(row_sp);
}
return plan_sp;
}
-SymbolVendor &SymbolFileBreakpad::GetSymbolVendor() {
- return *m_obj_file->GetModule()->GetSymbolVendor();
+UnwindPlanSP
+SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+ addr_t base = GetBaseFileAddress();
+ if (base == LLDB_INVALID_ADDRESS)
+ return nullptr;
+
+ LineIterator It(*m_objfile_sp, Record::StackWin, bookmark);
+ llvm::Optional<StackWinRecord> record = StackWinRecord::parse(*It);
+ assert(record.hasValue() &&
+ "Record already parsed successfully in ParseUnwindData!");
+
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
+ plan_sp->SetSourceName("breakpad STACK WIN");
+ plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
+ plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
+ plan_sp->SetPlanValidAddressRange(
+ AddressRange(base + record->RVA, record->CodeSize,
+ m_objfile_sp->GetModule()->GetSectionList()));
+
+ auto row_sp = std::make_shared<UnwindPlan::Row>();
+ row_sp->SetOffset(0);
+
+ llvm::BumpPtrAllocator node_alloc;
+ std::vector<std::pair<llvm::StringRef, postfix::Node *>> program =
+ postfix::ParseFPOProgram(record->ProgramString, node_alloc);
+
+ if (program.empty()) {
+ LLDB_LOG(log, "Invalid unwind rule: {0}.", record->ProgramString);
+ return nullptr;
+ }
+ auto it = program.begin();
+ const auto &symbol_resolver =
+ [&](postfix::SymbolNode &symbol) -> postfix::Node * {
+ llvm::StringRef name = symbol.GetName();
+ for (const auto &rule : llvm::make_range(program.begin(), it)) {
+ if (rule.first == name)
+ return rule.second;
+ }
+ if (const RegisterInfo *info = ResolveRegister(resolver, name))
+ return postfix::MakeNode<postfix::RegisterNode>(
+ node_alloc, info->kinds[eRegisterKindLLDB]);
+ return nullptr;
+ };
+
+ // We assume the first value will be the CFA. It is usually called T0, but
+ // clang will use T1, if it needs to realign the stack.
+ auto *symbol = llvm::dyn_cast<postfix::SymbolNode>(it->second);
+ if (symbol && symbol->GetName() == ".raSearch") {
+ row_sp->GetCFAValue().SetRaSearch(record->LocalSize +
+ record->SavedRegisterSize);
+ } else {
+ if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+ LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
+ record->ProgramString);
+ return nullptr;
+ }
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+ row_sp->GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
+ }
+
+ // Replace the node value with InitialValueNode, so that subsequent
+ // expressions refer to the CFA value instead of recomputing the whole
+ // expression.
+ it->second = postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
+
+
+ // Now process the rest of the assignments.
+ for (++it; it != program.end(); ++it) {
+ const RegisterInfo *info = ResolveRegister(resolver, it->first);
+ // It is not an error if the resolution fails because the program may
+ // contain temporary variables.
+ if (!info)
+ continue;
+ if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+ LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
+ record->ProgramString);
+ return nullptr;
+ }
+
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+ UnwindPlan::Row::RegisterLocation loc;
+ loc.SetIsDWARFExpression(saved.data(), saved.size());
+ row_sp->SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
+ }
+
+ plan_sp->AppendRow(row_sp);
+ return plan_sp;
}
addr_t SymbolFileBreakpad::GetBaseFileAddress() {
- return m_obj_file->GetModule()
+ return m_objfile_sp->GetModule()
->GetObjectFile()
->GetBaseAddress()
.GetFileAddress();
@@ -569,8 +671,8 @@ void SymbolFileBreakpad::ParseCUData() {
// We shall create one compile unit for each FUNC record. So, count the number
// of FUNC records, and store them in m_cu_data, together with their ranges.
- for (LineIterator It(*m_obj_file, Record::Func), End(*m_obj_file); It != End;
- ++It) {
+ for (LineIterator It(*m_objfile_sp, Record::Func), End(*m_objfile_sp);
+ It != End; ++It) {
if (auto record = FuncRecord::parse(*It)) {
m_cu_data->Append(CompUnitMap::Entry(base + record->Address, record->Size,
CompUnitData(It.GetBookmark())));
@@ -589,7 +691,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
"How did we create compile units without a base address?");
SupportFileMap map;
- data.line_table_up = llvm::make_unique<LineTable>(&cu);
+ data.line_table_up = std::make_unique<LineTable>(&cu);
std::unique_ptr<LineSequence> line_seq_up(
data.line_table_up->CreateLineSequenceContainer());
llvm::Optional<addr_t> next_addr;
@@ -603,7 +705,8 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
line_seq_up->Clear();
};
- LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::Func, data.bookmark),
+ End(*m_objfile_sp);
assert(Record::classify(*It) == Record::Func);
for (++It; It != End; ++It) {
auto record = LineRecord::parse(*It);
@@ -631,8 +734,8 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
void SymbolFileBreakpad::ParseUnwindData() {
if (m_unwind_data)
return;
-
m_unwind_data.emplace();
+
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS) {
@@ -640,14 +743,24 @@ void SymbolFileBreakpad::ParseUnwindData() {
"of object file.");
}
- for (LineIterator It(*m_obj_file, Record::StackCFI), End(*m_obj_file);
+ for (LineIterator It(*m_objfile_sp, Record::StackCFI), End(*m_objfile_sp);
It != End; ++It) {
if (auto record = StackCFIRecord::parse(*It)) {
if (record->Size)
- m_unwind_data->Append(UnwindMap::Entry(
+ m_unwind_data->cfi.Append(UnwindMap::Entry(
base + record->Address, *record->Size, It.GetBookmark()));
} else
LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
}
- m_unwind_data->Sort();
+ m_unwind_data->cfi.Sort();
+
+ for (LineIterator It(*m_objfile_sp, Record::StackWin), End(*m_objfile_sp);
+ It != End; ++It) {
+ if (auto record = StackWinRecord::parse(*It)) {
+ m_unwind_data->win.Append(UnwindMap::Entry(
+ base + record->RVA, record->CodeSize, It.GetBookmark()));
+ } else
+ LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
+ }
+ m_unwind_data->win.Sort();
}
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 8a0b7645fd0a..a10138cdf92f 100644
--- a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -12,6 +12,7 @@
#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -31,12 +32,13 @@ public:
return "Breakpad debug symbol file reader.";
}
- static SymbolFile *CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileBreakpad(obj_file);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp) {
+ return new SymbolFileBreakpad(std::move(objfile_sp));
}
// Constructors and Destructors
- SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {}
+ SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)) {}
~SymbolFileBreakpad() override {}
@@ -46,10 +48,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override {
return lldb::eLanguageTypeUnknown;
}
@@ -72,12 +70,10 @@ public:
size_t ParseBlocksRecursive(Function &func) override { return 0; }
- uint32_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t max_matches,
- VariableList &variables) override {
- return 0;
- }
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override {}
size_t ParseVariablesForContext(const SymbolContext &sc) override {
return 0;
@@ -99,31 +95,30 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
- size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
- TypeList &type_list) override {
- return 0;
- }
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override {}
- uint32_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) override;
+ void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
- bool append, SymbolContextList &sc_list) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
- uint32_t FindTypes(ConstString name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
- size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
- TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ TypeMap &types) override;
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override {
- return nullptr;
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language) override {
+ return llvm::make_error<llvm::StringError>(
+ "SymbolFileBreakpad does not support GetTypeSystemForLanguage",
+ llvm::inconvertibleErrorCode());
}
CompilerDeclContext
@@ -134,6 +129,8 @@ public:
void AddSymbols(Symtab &symtab) override;
+ llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override;
+
lldb::UnwindPlanSP
GetUnwindPlan(const Address &address,
const RegisterInfoResolver &resolver) override;
@@ -196,15 +193,22 @@ private:
};
- SymbolVendor &GetSymbolVendor();
+ uint32_t CalculateNumCompileUnits() override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
lldb::addr_t GetBaseFileAddress();
void ParseFileRecords();
void ParseCUData();
void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data);
void ParseUnwindData();
- bool ParseUnwindRow(llvm::StringRef unwind_rules,
- const RegisterInfoResolver &resolver,
- UnwindPlan::Row &row);
+ llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node);
+ lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver);
+ bool ParseCFIUnwindRow(llvm::StringRef unwind_rules,
+ const RegisterInfoResolver &resolver,
+ UnwindPlan::Row &row);
+ lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver);
using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>;
@@ -212,7 +216,11 @@ private:
llvm::Optional<CompUnitMap> m_cu_data;
using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>;
- llvm::Optional<UnwindMap> m_unwind_data;
+ struct UnwindData {
+ UnwindMap cfi;
+ UnwindMap win;
+ };
+ llvm::Optional<UnwindData> m_unwind_data;
llvm::BumpPtrAllocator m_allocator;
};
diff --git a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index 9ae047da1325..0a5073b8cd9e 100644
--- a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -21,30 +21,30 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
Module &module, DWARFDataExtractor apple_names,
DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
- auto apple_names_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_names_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_names, debug_str, ".apple_names");
if (!apple_names_table_up->IsValid())
apple_names_table_up.reset();
auto apple_namespaces_table_up =
- llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ std::make_unique<DWARFMappedHash::MemoryTable>(
apple_namespaces, debug_str, ".apple_namespaces");
if (!apple_namespaces_table_up->IsValid())
apple_namespaces_table_up.reset();
- auto apple_types_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_types, debug_str, ".apple_types");
if (!apple_types_table_up->IsValid())
apple_types_table_up.reset();
- auto apple_objc_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_objc, debug_str, ".apple_objc");
if (!apple_objc_table_up->IsValid())
apple_objc_table_up.reset();
if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
apple_objc_table_up)
- return llvm::make_unique<AppleDWARFIndex>(
+ 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));
@@ -110,6 +110,7 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
const bool has_qualified_name_hash =
m_apple_types_up->GetHeader().header_data.ContainsAtom(
DWARFMappedHash::eAtomTypeQualNameHash);
+
const ConstString type_name(context[0].name);
const dw_tag_t tag = context[0].tag;
if (has_tag && has_qualified_name_hash) {
@@ -119,12 +120,32 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
type_name.GetStringRef(), tag, qualified_name_hash, offsets);
- } else if (has_tag) {
+ return;
+ }
+
+ if (has_tag) {
+ // When searching for a scoped type (for example,
+ // "std::vector<int>::const_iterator") searching for the innermost
+ // name alone ("const_iterator") could yield many false
+ // positives. By searching for the parent type ("vector<int>")
+ // first we can avoid extracting type DIEs from object files that
+ // would fail the filter anyway.
+ if (!has_qualified_name_hash && (context.GetSize() > 1) &&
+ (context[1].tag == DW_TAG_class_type ||
+ context[1].tag == DW_TAG_structure_type)) {
+ DIEArray class_matches;
+ m_apple_types_up->FindByName(context[1].name, class_matches);
+ if (class_matches.empty())
+ return;
+ }
+
if (log)
m_module.LogMessage(log, "FindByNameAndTag()");
m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
- } else
- m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
+ return;
+ }
+
+ m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
}
void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index e7927b31b9c3..7ee4727cde91 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -28,7 +28,6 @@ public:
virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
const DWARFDIE &die,
- lldb_private::Log *log,
bool *type_is_new_ptr) = 0;
virtual lldb_private::Function *
@@ -48,8 +47,8 @@ public:
virtual lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual std::vector<DWARFDIE>
- GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0;
+ virtual void EnsureAllDIEsInDeclContextHaveBeenParsed(
+ lldb_private::CompilerDeclContext decl_context) = 0;
static llvm::Optional<lldb_private::SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE &parent_die,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index b85ab54a10d3..636e6032b877 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -9,7 +9,6 @@
#include <stdlib.h>
#include "DWARFASTParserClang.h"
-#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
@@ -28,7 +27,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/Language.h"
@@ -144,23 +143,27 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
// If this type comes from a Clang module, look in the DWARF section
// of the pcm file in the module cache. Clang generates DWO skeleton
// units as breadcrumbs to find them.
- std::vector<CompilerContext> decl_context;
+ llvm::SmallVector<CompilerContext, 4> decl_context;
die.GetDeclContext(decl_context);
TypeMap dwo_types;
- if (!dwo_module_sp->GetSymbolVendor()->FindTypes(decl_context, true,
- dwo_types)) {
+ // The type in the Clang module must have the same language as the current CU.
+ LanguageSet languages;
+ languages.Insert(die.GetCU()->GetLanguageType());
+ dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, dwo_types);
+ if (dwo_types.Empty()) {
if (!IsClangModuleFwdDecl(die))
return TypeSP();
- // Since this this type is defined in one of the Clang modules imported by
- // this symbol file, search all of them.
+ // Since this type is defined in one of the Clang modules imported
+ // by this symbol file, search all of them.
auto &sym_file = die.GetCU()->GetSymbolFileDWARF();
for (const auto &name_module : sym_file.getExternalTypeModules()) {
if (!name_module.second)
continue;
- SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
- if (sym_vendor->FindTypes(decl_context, true, dwo_types))
+ name_module.second->GetSymbolFile()->FindTypes(decl_context,
+ languages, dwo_types);
+ if (dwo_types.GetSize())
break;
}
}
@@ -188,7 +191,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
&dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward));
- dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->GetTypeList().Insert(type_sp);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
if (tag_decl)
@@ -228,42 +231,7 @@ static void CompleteExternalTagDeclType(ClangASTImporter &ast_importer,
}
}
-namespace {
-/// 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 ParsedTypeAttributes {
- explicit ParsedTypeAttributes(const DWARFDIE &die);
-
- AccessType accessibility = eAccessNone;
- bool is_artificial = false;
- bool is_complete_objc_class = false;
- bool is_explicit = false;
- bool is_forward_declaration = false;
- bool is_inline = false;
- bool is_scoped_enum = false;
- bool is_vector = false;
- bool is_virtual = false;
- clang::StorageClass storage = clang::SC_None;
- const char *mangled_name = nullptr;
- ConstString name;
- Declaration decl;
- DWARFDIE object_pointer;
- DWARFFormValue abstract_origin;
- DWARFFormValue containing_type;
- DWARFFormValue signature;
- DWARFFormValue specification;
- DWARFFormValue type;
- LanguageType class_language = eLanguageTypeUnknown;
- llvm::Optional<uint64_t> byte_size;
- size_t calling_convention = llvm::dwarf::DW_CC_normal;
- uint32_t bit_stride = 0;
- uint32_t byte_stride = 0;
- uint32_t encoding = 0;
-};
-} // namespace
-
-ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die) {
+ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
DWARFAttributes attributes;
size_t num_attributes = die.GetAttributes(attributes);
for (size_t i = 0; i < num_attributes; ++i) {
@@ -390,13 +358,17 @@ static std::string GetUnitName(const DWARFDIE &die) {
}
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
- const DWARFDIE &die, Log *log,
+ const DWARFDIE &die,
bool *type_is_new_ptr) {
if (type_is_new_ptr)
*type_is_new_ptr = false;
if (!die)
return nullptr;
+
+ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS));
+
SymbolFileDWARF *dwarf = die.GetDWARF();
if (log) {
DWARFDIE context_die;
@@ -420,11 +392,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// Set a bit that lets us know that we are currently parsing this
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
- ParsedTypeAttributes attrs(die);
+ ParsedDWARFTypeAttributes attrs(die);
if (DWARFDIE signature_die = attrs.signature.Reference()) {
if (TypeSP type_sp =
- ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr)) {
+ ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) {
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
if (clang::DeclContext *decl_ctx =
GetCachedClangDeclContextForDIE(signature_die))
@@ -434,7 +406,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
return nullptr;
}
- TypeList *type_list = dwarf->GetTypeList();
if (type_is_new_ptr)
*type_is_new_ptr = true;
@@ -562,7 +533,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
bool function_type_is_new_pointer;
TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
- sc, function_type, log, &function_type_is_new_pointer);
+ sc, function_type, &function_type_is_new_pointer);
if (lldb_function_type_sp) {
clang_type = m_ast.CreateBlockPointerType(
@@ -660,370 +631,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type: {
- // UniqueDWARFASTType is large, so don't create a local variables on
- // the stack, put it on the heap. This function is often called
- // recursively and clang isn't good and sharing the stack space for
- // variables in different blocks.
- std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_up(
- new UniqueDWARFASTType());
-
- ConstString unique_typename(attrs.name);
- Declaration unique_decl(attrs.decl);
-
- if (attrs.name) {
- if (Language::LanguageIsCPlusPlus(cu_language)) {
- // For C++, we rely solely upon the one definition rule that says
- // only one thing can exist at a given decl context. We ignore the
- // file and line that things are declared on.
- std::string qualified_name;
- if (die.GetQualifiedName(qualified_name))
- unique_typename = ConstString(qualified_name);
- unique_decl.Clear();
- }
-
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
- *unique_ast_entry_up)) {
- type_sp = unique_ast_entry_up->m_type_sp;
- if (type_sp) {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type) {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_union_type) {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_class_type) {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
-
- if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
- !die.HasChildren() && cu_language == eLanguageTypeObjC) {
- // Work around an issue with clang at the moment where forward
- // declarations for objective C classes are emitted as:
- // DW_TAG_structure_type [2]
- // DW_AT_name( "ForwardObjcClass" )
- // DW_AT_byte_size( 0x00 )
- // DW_AT_decl_file( "..." )
- // DW_AT_decl_line( 1 )
- //
- // Note that there is no DW_AT_declaration and there are no children,
- // and the byte size is zero.
- attrs.is_forward_declaration = true;
- }
-
- if (attrs.class_language == eLanguageTypeObjC ||
- attrs.class_language == eLanguageTypeObjC_plus_plus) {
- if (!attrs.is_complete_objc_class &&
- die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // We have a valid eSymbolTypeObjCClass class symbol whose name
- // matches the current objective C class that we are trying to find
- // and this DIE isn't the complete definition (we checked
- // is_complete_objc_class above and know it is false), so the real
- // definition is in here somewhere
- type_sp =
- dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
- die, attrs.name, true);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
- "incomplete objc type, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
-
- if (attrs.is_forward_declaration) {
- // We have a forward declaration to a type and we need to try and
- // find a full declaration. We look in the current type index just in
- // case we have a forward declaration followed by an actual
- // declarations in the DWARF. If this fails, we need to look
- // elsewhere...
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, trying to find complete type",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString());
- }
-
- // See if the type comes from a DWO module and if so, track down that
- // type.
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
- // type_name_const_str);
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF, see
- // if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
- die_decl_ctx);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx =
- GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
- }
- assert(tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type.SetCompilerType(
- &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!clang_type) {
- clang::DeclContext *decl_ctx =
- GetClangDeclContextContainingDIE(die, nullptr);
-
- // If your decl context is a record that was imported from another
- // AST context (in the gmodules case), we need to make sure the type
- // backing the Decl is complete before adding children to it. This is
- // not an issue in the non-gmodules case because the debug info will
- // always contain a full definition of parent types in that case.
- CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
- attrs.name.GetCString());
-
- if (attrs.accessibility == eAccessNone && decl_ctx) {
- // Check the decl context that contains this class/struct/union. If
- // it is a class we must give it an accessibility.
- const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
- if (DeclKindIsCXXClass(containing_decl_kind))
- attrs.accessibility = default_accessibility;
- }
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
- metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
-
- if (attrs.name.GetStringRef().contains('<')) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- if (ParseTemplateParameterInfos(die, template_param_infos)) {
- clang::ClassTemplateDecl *class_template_decl =
- m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
- attrs.name.GetCString(),
- tag_decl_kind, template_param_infos);
- if (!class_template_decl) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
- "clang::ClassTemplateDecl failed to return a decl.",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString());
- }
- return TypeSP();
- }
-
- clang::ClassTemplateSpecializationDecl *class_specialization_decl =
- m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, class_template_decl, tag_decl_kind,
- template_param_infos);
- clang_type = m_ast.CreateClassTemplateSpecializationType(
- class_specialization_decl);
- clang_type_was_created = true;
-
- m_ast.SetMetadata(class_template_decl, metadata);
- m_ast.SetMetadata(class_specialization_decl, metadata);
- }
- }
-
- if (!clang_type_was_created) {
- clang_type_was_created = true;
- clang_type = m_ast.CreateRecordType(
- decl_ctx, attrs.accessibility, attrs.name.GetCString(),
- tag_decl_kind, attrs.class_language, &metadata);
- }
- }
-
- // Store a forward declaration to this class type in case any
- // parameters in any class methods need it for the clang types for
- // function prototypes.
- LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
- type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
- attrs.byte_size, nullptr, LLDB_INVALID_UID,
- Type::eEncodingIsUID, &attrs.decl, clang_type,
- Type::eResolveStateForward);
-
- type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class);
-
- // Add our type to the unique type map so we don't end up creating many
- // copies of the same type over and over in the ASTContext for our
- // module
- unique_ast_entry_up->m_type_sp = type_sp;
- unique_ast_entry_up->m_die = die;
- unique_ast_entry_up->m_declaration = unique_decl;
- unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
- dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
- *unique_ast_entry_up);
-
- if (attrs.is_forward_declaration && die.HasChildren()) {
- // Check to see if the DIE actually has a definition, some version of
- // GCC will
- // emit DIEs with DW_AT_declaration set to true, but yet still have
- // subprogram, members, or inheritance, so we can't trust it
- DWARFDIE child_die = die.GetFirstChild();
- while (child_die) {
- switch (child_die.Tag()) {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- child_die.Clear();
- attrs.is_forward_declaration = false;
- break;
- default:
- child_die = child_die.GetSibling();
- break;
- }
- }
- }
-
- if (!attrs.is_forward_declaration) {
- // Always start the definition for a class type so that if the class
- // has child classes or types that require the class to be created
- // for use as their decl contexts the class will be ready to accept
- // these child definitions.
- if (!die.HasChildren()) {
- // No children for this struct/union/class, lets finish it
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
- "definition.\nPlease file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), attrs.name.GetCString());
- }
-
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
- clang::RecordDecl *record_decl =
- ClangASTContext::GetAsRecordDecl(clang_type);
-
- if (record_decl) {
- GetClangASTImporter().InsertRecordDecl(
- record_decl, ClangASTImporter::LayoutInfo());
- }
- }
- } else if (clang_type_was_created) {
- // Start the definition if the class is not objective C since the
- // underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++
- // class/union/structs we want to start the definition in case the
- // class is needed as the declaration context for a contained class
- // or type without the need to complete that type..
-
- if (attrs.class_language != eLanguageTypeObjC &&
- attrs.class_language != eLanguageTypeObjC_plus_plus)
- ClangASTContext::StartTagDeclarationDefinition(clang_type);
-
- // Leave this as a forward declaration until we need to know the
- // details of the type. lldb_private::Type will automatically call
- // the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)" When the definition
- // needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().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()] =
- clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()
- [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
- die.GetID();
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
- }
- }
-
- // If we made a clang type, set the trivial abi if applicable: We only
- // do this for pass by value - which implies the Trivial ABI. There
- // isn't a way to assert that something that would normally be pass by
- // value is pass by reference, so we ignore that attribute if set.
- if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl) {
- record_decl->setHasTrivialSpecialMemberForCall();
- }
- }
-
- if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl)
- record_decl->setArgPassingRestrictions(
- clang::RecordDecl::APK_CannotPassInRegs);
- }
-
- } break;
+ assert((!type_sp && !clang_type) &&
+ "Did not expect partially computed structure-like type");
+ TypeSP struct_like_type_sp = ParseStructureLikeDIE(die, attrs);
+ return UpdateSymbolContextScopeForType(sc, die, struct_like_type_sp);
+ }
case DW_TAG_enumeration_type: {
if (attrs.is_forward_declaration) {
@@ -1395,8 +1007,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
is_attr_used, attrs.is_artificial);
type_handled = cxx_method_decl != NULL;
+ // Artificial methods are always handled even when we
+ // don't create a new declaration for them.
+ type_handled |= attrs.is_artificial;
- if (type_handled) {
+ if (cxx_method_decl) {
LinkDeclContextToDIE(
ClangASTContext::GetAsDeclContext(cxx_method_decl),
die);
@@ -1407,12 +1022,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (!object_pointer_name.empty()) {
metadata.SetObjectPtrName(
object_pointer_name.c_str());
- if (log)
- log->Printf(
- "Setting object pointer name: %s on method "
- "object %p.\n",
- object_pointer_name.c_str(),
- static_cast<void *>(cxx_method_decl));
+ LLDB_LOGF(log,
+ "Setting object pointer name: %s on method "
+ "object %p.\n",
+ object_pointer_name.c_str(),
+ static_cast<void *>(cxx_method_decl));
}
m_ast.SetMetadata(cxx_method_decl, metadata);
} else {
@@ -1520,11 +1134,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (!object_pointer_name.empty()) {
metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf("Setting object pointer name: %s on function "
- "object %p.",
- object_pointer_name.c_str(),
- static_cast<void *>(function_decl));
+ LLDB_LOGF(log,
+ "Setting object pointer name: %s on function "
+ "object %p.",
+ object_pointer_name.c_str(),
+ static_cast<void *>(function_decl));
}
m_ast.SetMetadata(function_decl, metadata);
}
@@ -1651,31 +1265,418 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
break;
}
- if (type_sp.get()) {
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+ // TODO: We should consider making the switch above exhaustive to simplify
+ // control flow in ParseTypeFromDWARF. Then, we could simply replace this
+ // return statement with a call to llvm_unreachable.
+ return UpdateSymbolContextScopeForType(sc, die, type_sp);
+}
+
+TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
+ const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
+ if (!type_sp)
+ return type_sp;
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ TypeList &type_list = dwarf->GetTypeList();
+ DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+ dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+ SymbolContextScope *symbol_context_scope = NULL;
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
+ symbol_context_scope = sc.comp_unit;
+ } else if (sc.function != NULL && sc_parent_die) {
+ symbol_context_scope =
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == NULL)
+ symbol_context_scope = sc.function;
+ } else {
+ symbol_context_scope = sc.module_sp.get();
+ }
+
+ if (symbol_context_scope != NULL)
+ type_sp->SetSymbolContextScope(symbol_context_scope);
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != NULL && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- } else
- symbol_context_scope = sc.module_sp.get();
+ // We are ready to put this type into the uniqued list up at the module
+ // level.
+ type_list.Insert(type_sp);
- if (symbol_context_scope != NULL) {
- type_sp->SetSymbolContextScope(symbol_context_scope);
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+}
+
+TypeSP
+DWARFASTParserClang::ParseStructureLikeDIE(const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs) {
+ TypeSP type_sp;
+ CompilerType clang_type;
+ const dw_tag_t tag = die.Tag();
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ LanguageType cu_language = die.GetLanguage();
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS);
+
+ // UniqueDWARFASTType is large, so don't create a local variables on the
+ // stack, put it on the heap. This function is often called recursively and
+ // clang isn't good at sharing the stack space for variables in different
+ // blocks.
+ auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();
+
+ ConstString unique_typename(attrs.name);
+ Declaration unique_decl(attrs.decl);
+
+ if (attrs.name) {
+ if (Language::LanguageIsCPlusPlus(cu_language)) {
+ // For C++, we rely solely upon the one definition rule that says
+ // only one thing can exist at a given decl context. We ignore the
+ // file and line that things are declared on.
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
+ }
+
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
+ *unique_ast_entry_up)) {
+ type_sp = unique_ast_entry_up->m_type_sp;
+ if (type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ LinkDeclContextToDIE(
+ GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
+ return type_sp;
+ }
}
+ }
- // We are ready to put this type into the uniqued list up at the module
- // level
- type_list->Insert(type_sp);
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ int tag_decl_kind = -1;
+ AccessType default_accessibility = eAccessNone;
+ if (tag == DW_TAG_structure_type) {
+ tag_decl_kind = clang::TTK_Struct;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_union_type) {
+ tag_decl_kind = clang::TTK_Union;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_class_type) {
+ tag_decl_kind = clang::TTK_Class;
+ default_accessibility = eAccessPrivate;
+ }
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+ !die.HasChildren() && cu_language == eLanguageTypeObjC) {
+ // Work around an issue with clang at the moment where forward
+ // declarations for objective C classes are emitted as:
+ // DW_TAG_structure_type [2]
+ // DW_AT_name( "ForwardObjcClass" )
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_decl_file( "..." )
+ // DW_AT_decl_line( 1 )
+ //
+ // Note that there is no DW_AT_declaration and there are no children,
+ // and the byte size is zero.
+ attrs.is_forward_declaration = true;
+ }
+
+ if (attrs.class_language == eLanguageTypeObjC ||
+ attrs.class_language == eLanguageTypeObjC_plus_plus) {
+ if (!attrs.is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // We have a valid eSymbolTypeObjCClass class symbol whose name
+ // matches the current objective C class that we are trying to find
+ // and this DIE isn't the complete definition (we checked
+ // is_complete_objc_class above and know it is false), so the real
+ // definition is in here somewhere
+ type_sp =
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, attrs.name, true);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
+ "incomplete objc type, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
+ }
+
+ if (attrs.is_forward_declaration) {
+ // We have a forward declaration to a type and we need to try and
+ // find a full declaration. We look in the current type index just in
+ // case we have a forward declaration followed by an actual
+ // declarations in the DWARF. If this fails, we need to look
+ // elsewhere...
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, trying to find complete type",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ attrs.name.GetCString());
+ }
+
+ // See if the type comes from a DWO module and if so, track down that
+ // type.
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
+ // type_name_const_str);
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ assert(tag_decl_kind != -1);
+ bool clang_type_was_created = false;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
+
+ // If your decl context is a record that was imported from another
+ // AST context (in the gmodules case), we need to make sure the type
+ // backing the Decl is complete before adding children to it. This is
+ // not an issue in the non-gmodules case because the debug info will
+ // always contain a full definition of parent types in that case.
+ CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+ attrs.name.GetCString());
+
+ if (attrs.accessibility == eAccessNone && decl_ctx) {
+ // Check the decl context that contains this class/struct/union. If
+ // it is a class we must give it an accessibility.
+ const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
+ if (DeclKindIsCXXClass(containing_decl_kind))
+ attrs.accessibility = default_accessibility;
+ }
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
+
+ if (attrs.name.GetStringRef().contains('<')) {
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ if (ParseTemplateParameterInfos(die, template_param_infos)) {
+ clang::ClassTemplateDecl *class_template_decl =
+ m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
+ attrs.name.GetCString(), tag_decl_kind,
+ template_param_infos);
+ if (!class_template_decl) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
+ "clang::ClassTemplateDecl failed to return a decl.",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString());
+ }
+ return TypeSP();
+ }
+
+ clang::ClassTemplateSpecializationDecl *class_specialization_decl =
+ m_ast.CreateClassTemplateSpecializationDecl(
+ decl_ctx, class_template_decl, tag_decl_kind,
+ template_param_infos);
+ clang_type = m_ast.CreateClassTemplateSpecializationType(
+ class_specialization_decl);
+ clang_type_was_created = true;
+
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+ }
+ }
+
+ if (!clang_type_was_created) {
+ clang_type_was_created = true;
+ clang_type = m_ast.CreateRecordType(
+ decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind,
+ attrs.class_language, &metadata);
+ }
+ }
+
+ // Store a forward declaration to this class type in case any
+ // parameters in any class methods need it for the clang types for
+ // function prototypes.
+ LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
+ type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
+ attrs.byte_size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &attrs.decl,
+ clang_type, Type::eResolveStateForward);
+
+ type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class);
+
+ // Add our type to the unique type map so we don't end up creating many
+ // copies of the same type over and over in the ASTContext for our
+ // module
+ unique_ast_entry_up->m_type_sp = type_sp;
+ unique_ast_entry_up->m_die = die;
+ unique_ast_entry_up->m_declaration = unique_decl;
+ unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
+ *unique_ast_entry_up);
+
+ if (attrs.is_forward_declaration && die.HasChildren()) {
+ // Check to see if the DIE actually has a definition, some version of
+ // GCC will
+ // emit DIEs with DW_AT_declaration set to true, but yet still have
+ // subprogram, members, or inheritance, so we can't trust it
+ DWARFDIE child_die = die.GetFirstChild();
+ while (child_die) {
+ switch (child_die.Tag()) {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ case DW_TAG_member:
+ case DW_TAG_APPLE_property:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ child_die.Clear();
+ attrs.is_forward_declaration = false;
+ break;
+ default:
+ child_die = child_die.GetSibling();
+ break;
+ }
+ }
+ }
+
+ if (!attrs.is_forward_declaration) {
+ // Always start the definition for a class type so that if the class
+ // has child classes or types that require the class to be created
+ // for use as their decl contexts the class will be ready to accept
+ // these child definitions.
+ if (!die.HasChildren()) {
+ // No children for this struct/union/class, lets finish it
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), attrs.name.GetCString());
+ }
+
+ if (tag == DW_TAG_structure_type) // this only applies in C
+ {
+ clang::RecordDecl *record_decl =
+ ClangASTContext::GetAsRecordDecl(clang_type);
+
+ if (record_decl) {
+ GetClangASTImporter().InsertRecordDecl(
+ record_decl, ClangASTImporter::LayoutInfo());
+ }
+ }
+ } else if (clang_type_was_created) {
+ // Start the definition if the class is not objective C since the
+ // underlying decls respond to isCompleteDefinition(). Objective
+ // C decls don't respond to isCompleteDefinition() so we can't
+ // start the declaration definition right away. For C++
+ // class/union/structs we want to start the definition in case the
+ // class is needed as the declaration context for a contained class
+ // or type without the need to complete that type..
+
+ if (attrs.class_language != eLanguageTypeObjC &&
+ attrs.class_language != eLanguageTypeObjC_plus_plus)
+ ClangASTContext::StartTagDeclarationDefinition(clang_type);
+
+ // Leave this as a forward declaration until we need to know the
+ // details of the type. lldb_private::Type will automatically call
+ // the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)" When the definition
+ // needs to be defined.
+ assert(!dwarf->GetForwardDeclClangTypeToDie().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()] =
+ clang_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()
+ [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
+ die.GetID();
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+ }
+ }
+
+ // If we made a clang type, set the trivial abi if applicable: We only
+ // do this for pass by value - which implies the Trivial ABI. There
+ // isn't a way to assert that something that would normally be pass by
+ // value is pass by reference, so we ignore that attribute if set.
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl && record_decl->getDefinition()) {
+ record_decl->setHasTrivialSpecialMemberForCall();
+ }
+ }
+
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl)
+ record_decl->setArgPassingRestrictions(
+ clang::RecordDecl::APK_CannotPassInRegs);
}
return type_sp;
}
@@ -2181,14 +2182,16 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
return false;
}
-std::vector<DWARFDIE> DWARFASTParserClang::GetDIEForDeclContext(
+void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(
lldb_private::CompilerDeclContext decl_context) {
- std::vector<DWARFDIE> result;
- for (auto it = m_decl_ctx_to_die.find(
- (clang::DeclContext *)decl_context.GetOpaqueDeclContext());
- it != m_decl_ctx_to_die.end(); it++)
- result.push_back(it->second);
- return result;
+ auto opaque_decl_ctx =
+ (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
+ for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);
+ it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;
+ it = m_decl_ctx_to_die.erase(it))
+ for (DWARFDIE decl = it->second.GetFirstChild(); decl;
+ decl = decl.GetSibling())
+ GetClangDeclForDIE(decl);
}
CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
@@ -2530,9 +2533,11 @@ bool DWARFASTParserClang::ParseChildMembers(
if (DWARFExpression::Evaluate(
nullptr, // ExecutionContext *
nullptr, // RegisterContext *
- module_sp, debug_info_data, die.GetCU(), block_offset,
- block_length, eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, 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();
}
@@ -2965,11 +2970,12 @@ bool DWARFASTParserClang::ParseChildMembers(
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,
- debug_info_data, die.GetCU(),
- block_offset, block_length,
- eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, nullptr)) {
+ 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();
}
@@ -3270,6 +3276,8 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
array_info.element_orders.push_back(num_elements);
}
} break;
+ default:
+ break;
}
}
return array_info;
@@ -3672,11 +3680,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
if (src_size != dst_size) {
if (src_size != 0 && dst_size != 0) {
- if (log)
- log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, "
- "but they didn't have the same size (src=%d, dst=%d)",
- src_class_die.GetOffset(), dst_class_die.GetOffset(),
- src_size, dst_size);
+ LLDB_LOGF(log,
+ "warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but they didn't have the same size (src=%d, dst=%d)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(), src_size,
+ dst_size);
}
fast_path = false;
@@ -3690,12 +3698,12 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
if (src_die.Tag() != dst_die.Tag()) {
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
- "but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
- src_class_die.GetOffset(), dst_class_die.GetOffset(),
- src_die.GetOffset(), src_die.GetTagAsCString(),
- dst_die.GetOffset(), dst_die.GetTagAsCString());
+ LLDB_LOGF(log,
+ "warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(),
+ src_die.GetOffset(), src_die.GetTagAsCString(),
+ dst_die.GetOffset(), dst_die.GetTagAsCString());
fast_path = false;
}
@@ -3706,12 +3714,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
if (src_name == dst_name || (strcmp(src_name, dst_name) == 0))
continue;
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
- "but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
- src_class_die.GetOffset(), dst_class_die.GetOffset(),
- src_die.GetOffset(), src_name, dst_die.GetOffset(),
- dst_name);
+ LLDB_LOGF(log,
+ "warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(),
+ src_die.GetOffset(), src_name, dst_die.GetOffset(), dst_name);
fast_path = false;
}
@@ -3733,32 +3740,31 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
if (src_decl_ctx) {
- if (log)
- log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
- dst_die.GetOffset());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
} else {
- if (log)
- log->Printf("warning: tried to unique decl context from 0x%8.8x for "
- "0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique decl context from 0x%8.8x for "
+ "0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
Type *src_child_type =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
if (src_child_type) {
- if (log)
- log->Printf(
- "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_child_type), src_child_type->GetID(),
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "uniquing type %p (uid=0x%" PRIx64
+ ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
} else {
- if (log)
- log->Printf("warning: tried to unique lldb_private::Type from "
- "0x%8.8x for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
}
} else {
@@ -3778,39 +3784,36 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
if (src_decl_ctx) {
- if (log)
- log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_decl_ctx),
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
} else {
- if (log)
- log->Printf("warning: tried to unique decl context from 0x%8.8x "
- "for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique decl context from 0x%8.8x "
+ "for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
Type *src_child_type =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
if (src_child_type) {
- if (log)
- log->Printf("uniquing type %p (uid=0x%" PRIx64
- ") from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_child_type),
- src_child_type->GetID(), src_die.GetOffset(),
- dst_die.GetOffset());
+ LLDB_LOGF(
+ log,
+ "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] =
src_child_type;
} else {
- if (log)
- log->Printf("warning: tried to unique lldb_private::Type from "
- "0x%8.8x for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
} else {
- if (log)
- log->Printf("warning: couldn't find a match for 0x%8.8x",
- dst_die.GetOffset());
+ LLDB_LOGF(log, "warning: couldn't find a match for 0x%8.8x",
+ dst_die.GetOffset());
failures.push_back(dst_die);
}
@@ -3836,32 +3839,31 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
if (src_decl_ctx) {
- if (log)
- log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
- dst_die.GetOffset());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
} else {
- if (log)
- log->Printf("warning: tried to unique decl context from 0x%8.8x "
- "for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique decl context from 0x%8.8x "
+ "for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
Type *src_child_type =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
if (src_child_type) {
- if (log)
- log->Printf(
- "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_child_type), src_child_type->GetID(),
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(
+ log,
+ "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
} else {
- if (log)
- log->Printf("warning: tried to unique lldb_private::Type from "
- "0x%8.8x for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
}
}
@@ -3872,10 +3874,10 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
ConstString dst_name_artificial =
dst_name_to_die_artificial.GetCStringAtIndex(idx);
dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
- if (log)
- log->Printf("warning: need to create artificial method for 0x%8.8x for "
- "method '%s'",
- dst_die.GetOffset(), dst_name_artificial.GetCString());
+ LLDB_LOGF(log,
+ "warning: need to create artificial method for 0x%8.8x for "
+ "method '%s'",
+ dst_die.GetOffset(), dst_name_artificial.GetCString());
failures.push_back(dst_die);
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 5b5d83d65932..106f9254a449 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -15,7 +15,10 @@
#include "llvm/ADT/SmallVector.h"
#include "DWARFASTParser.h"
+#include "DWARFDIE.h"
#include "DWARFDefines.h"
+#include "DWARFFormValue.h"
+#include "LogChannelDWARF.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -29,6 +32,8 @@ class CompileUnit;
class DWARFDebugInfoEntry;
class SymbolFileDWARF;
+struct ParsedDWARFTypeAttributes;
+
class DWARFASTParserClang : public DWARFASTParser {
public:
DWARFASTParserClang(lldb_private::ClangASTContext &ast);
@@ -37,7 +42,7 @@ public:
// DWARFASTParser interface.
lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, lldb_private::Log *log,
+ const DWARFDIE &die,
bool *type_is_new_ptr) override;
lldb_private::Function *
@@ -51,8 +56,8 @@ public:
lldb_private::CompilerDecl
GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
- std::vector<DWARFDIE>
- GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override;
+ void EnsureAllDIEsInDeclContextHaveBeenParsed(
+ lldb_private::CompilerDeclContext decl_context) override;
lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
@@ -63,9 +68,28 @@ public:
lldb_private::ClangASTImporter &GetClangASTImporter();
protected:
+ /// Protected typedefs and members.
+ /// @{
class DelayedAddObjCClassProperty;
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
+ typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+ DIEToDeclContextMap;
+ typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
+ DeclContextToDIEMap;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
+ DIEToDeclMap;
+ typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
+
+ lldb_private::ClangASTContext &m_ast;
+ DIEToDeclMap m_die_to_decl;
+ DeclToDIEMap m_decl_to_die;
+ DIEToDeclContextMap m_die_to_decl_ctx;
+ DeclContextToDIEMap m_decl_ctx_to_die;
+ std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
+ /// @}
+
clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
@@ -103,6 +127,10 @@ protected:
bool is_signed, uint32_t enumerator_byte_size,
const DWARFDIE &parent_die);
+ /// Parse a structure, class, or union type DIE.
+ lldb::TypeSP ParseStructureLikeDIE(const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
+
lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
@@ -123,29 +151,52 @@ protected:
void LinkDeclToDIE(clang::Decl *decl, const 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 ParseTypeFromDWO(const 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);
+};
- typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
- DIEToDeclContextMap;
- // typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet>
- // DeclContextToDIEMap;
- typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
- DeclContextToDIEMap;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
- DIEToDeclMap;
- typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
-
- lldb_private::ClangASTContext &m_ast;
- DIEToDeclMap m_die_to_decl;
- DeclToDIEMap m_decl_to_die;
- DIEToDeclContextMap m_die_to_decl_ctx;
- DeclContextToDIEMap m_decl_ctx_to_die;
- std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
+/// 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);
+
+ lldb::AccessType accessibility = lldb::eAccessNone;
+ bool is_artificial = false;
+ bool is_complete_objc_class = false;
+ bool is_explicit = false;
+ bool is_forward_declaration = false;
+ bool is_inline = false;
+ bool is_scoped_enum = false;
+ bool is_vector = false;
+ bool is_virtual = false;
+ clang::StorageClass storage = clang::SC_None;
+ 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::LanguageType class_language = lldb::eLanguageTypeUnknown;
+ llvm::Optional<uint64_t> byte_size;
+ size_t calling_convention = llvm::dwarf::DW_CC_normal;
+ uint32_t bit_stride = 0;
+ uint32_t byte_stride = 0;
+ uint32_t encoding = 0;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index 6128163a2926..741669b05754 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -18,7 +18,8 @@
using namespace lldb_private;
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
- : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {}
+ : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0),
+ m_attributes() {}
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
uint8_t has_children)
@@ -33,7 +34,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
return DWARFEnumState::Complete;
m_attributes.clear();
- m_tag = data.GetULEB128(offset_ptr);
+ m_tag = static_cast<dw_tag_t>(data.GetULEB128(offset_ptr));
if (m_tag == DW_TAG_null)
return llvm::make_error<llvm::object::GenericBinaryError>(
"abbrev decl requires non-null tag.");
@@ -68,7 +69,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
}
bool DWARFAbbreviationDeclaration::IsValid() {
- return m_code != 0 && m_tag != 0;
+ return m_code != 0 && m_tag != llvm::dwarf::DW_TAG_null;
}
uint32_t
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 96adb72c9532..033105efdc53 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -14,6 +14,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
using namespace lldb_private;
@@ -29,7 +30,7 @@ dw_tag_t DWARFBaseDIE::Tag() const {
if (m_die)
return m_die->Tag();
else
- return 0;
+ return llvm::dwarf::DW_TAG_null;
}
const char *DWARFBaseDIE::GetTagAsCString() const {
@@ -102,19 +103,22 @@ SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const {
return nullptr;
}
-lldb_private::TypeSystem *DWARFBaseDIE::GetTypeSystem() const {
- if (m_cu)
- return m_cu->GetTypeSystem();
- else
- return nullptr;
+llvm::Expected<lldb_private::TypeSystem &> DWARFBaseDIE::GetTypeSystem() const {
+ if (!m_cu)
+ return llvm::make_error<llvm::StringError>(
+ "Unable to get TypeSystem, no compilation unit available",
+ llvm::inconvertibleErrorCode());
+ return m_cu->GetTypeSystem();
}
DWARFASTParser *DWARFBaseDIE::GetDWARFParser() const {
- lldb_private::TypeSystem *type_system = GetTypeSystem();
- if (type_system)
- return type_system->GetDWARFParser();
- else
+ auto type_system_or_err = GetTypeSystem();
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DWARFASTParser");
return nullptr;
+ }
+ return type_system_or_err->GetDWARFParser();
}
bool DWARFBaseDIE::HasChildren() const {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 0058043017cd..9652d7946e87 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -12,6 +12,8 @@
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-types.h"
+#include "llvm/Support/Error.h"
+
class DIERef;
class DWARFASTParser;
class DWARFAttributes;
@@ -55,7 +57,7 @@ public:
llvm::Optional<DIERef> GetDIERef() const;
- lldb_private::TypeSystem *GetTypeSystem() const;
+ llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem() const;
DWARFASTParser *GetDWARFParser() const;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 9d97ca15a252..5ee0687995a1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -342,7 +342,8 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
}
}
-void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
+void DWARFDIE::GetDeclContext(
+ llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const {
const dw_tag_t tag = Tag();
if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
return;
@@ -351,40 +352,33 @@ void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
parent.GetDeclContext(context);
switch (tag) {
case DW_TAG_module:
- context.push_back(
- CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Module, ConstString(GetName())});
break;
case DW_TAG_namespace:
- context.push_back(CompilerContext(CompilerContextKind::Namespace,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Namespace, ConstString(GetName())});
break;
case DW_TAG_structure_type:
- context.push_back(CompilerContext(CompilerContextKind::Structure,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Struct, ConstString(GetName())});
break;
case DW_TAG_union_type:
- context.push_back(
- CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Union, ConstString(GetName())});
break;
case DW_TAG_class_type:
- context.push_back(
- CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Class, ConstString(GetName())});
break;
case DW_TAG_enumeration_type:
- context.push_back(CompilerContext(CompilerContextKind::Enumeration,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Enum, ConstString(GetName())});
break;
case DW_TAG_subprogram:
- context.push_back(CompilerContext(CompilerContextKind::Function,
- ConstString(GetPubname())));
+ context.push_back(
+ {CompilerContextKind::Function, ConstString(GetPubname())});
break;
case DW_TAG_variable:
- context.push_back(CompilerContext(CompilerContextKind::Variable,
- ConstString(GetPubname())));
+ context.push_back(
+ {CompilerContextKind::Variable, ConstString(GetPubname())});
break;
case DW_TAG_typedef:
- context.push_back(
- CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Typedef, ConstString(GetName())});
break;
default:
break;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 7753ec9008cb..a779c589611a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -78,8 +78,8 @@ public:
/// Return this DIE's decl context as it is needed to look up types
/// in Clang's -gmodules debug info format.
- void
- GetDeclContext(std::vector<lldb_private::CompilerContext> &context) const;
+ void GetDeclContext(
+ llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const;
// Getting attribute values from the DIE.
//
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index ccf33e6dc341..c8da2381353e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -66,8 +66,8 @@ void DWARFDebugAranges::Dump(Log *log) const {
for (size_t i = 0; i < num_entries; ++i) {
const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
if (entry)
- log->Printf("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data,
- entry->GetRangeBase(), entry->GetRangeEnd());
+ LLDB_LOGF(log, "0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data,
+ entry->GetRangeBase(), entry->GetRangeEnd());
}
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 100f35f8c6b0..1e04baca2c58 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -38,7 +38,7 @@ llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
if (m_cu_aranges_up)
return *m_cu_aranges_up;
- m_cu_aranges_up = llvm::make_unique<DWARFDebugAranges>();
+ m_cu_aranges_up = std::make_unique<DWARFDebugAranges>();
const DWARFDataExtractor &debug_aranges_data =
m_context.getOrLoadArangesData();
if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data))
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 2f55b7d40ed9..8c0fbeb4b717 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -192,7 +192,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
*offset_ptr = offset;
return true;
} else {
- m_tag = 0;
+ m_tag = llvm::dwarf::DW_TAG_null;
m_has_children = false;
return true; // NULL debug tag entry
}
@@ -340,18 +340,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- *frame_base = DWARFExpression(module, data, cu,
- block_offset, block_length);
+ *frame_base = DWARFExpression(
+ module, DataExtractor(data, block_offset, block_length), cu);
} else {
- const DWARFDataExtractor &debug_loc_data = dwarf.DebugLocData();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(
- cu, debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0) {
- *frame_base =
- DWARFExpression(module, debug_loc_data, cu,
- debug_loc_offset, loc_list_length);
+ DataExtractor data = dwarf.DebugLocData();
+ const dw_offset_t offset = form_value.Unsigned();
+ if (data.ValidOffset(offset)) {
+ data = DataExtractor(data, offset, data.GetByteSize() - offset);
+ *frame_base = DWARFExpression(module, data, cu);
if (lo_pc != LLDB_INVALID_ADDRESS) {
assert(lo_pc >= cu->GetBaseAddress());
frame_base->SetLocationListSlide(lo_pc -
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 1e7b5f27642d..25c885608d85 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -31,7 +31,7 @@ public:
DWARFDebugInfoEntry()
: m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
- m_has_children(false), m_abbr_idx(0), m_tag(0) {}
+ m_has_children(false), m_abbr_idx(0), m_tag(llvm::dwarf::DW_TAG_null) {}
explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
bool operator==(const DWARFDebugInfoEntry &rhs) const;
@@ -178,8 +178,9 @@ protected:
// a single NULL terminating child.
m_has_children : 1;
uint16_t m_abbr_idx;
- uint16_t m_tag; // A copy of the DW_TAG value so we don't have to go through
- // the compile unit abbrev table
+ /// A copy of the DW_TAG value so we don't have to go through the compile
+ /// unit abbrev table
+ dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
};
#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
deleted file mode 100644
index 953089fee22b..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ /dev/null
@@ -1,1038 +0,0 @@
-//===-- DWARFDebugLine.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 "DWARFDebugLine.h"
-
-//#define ENABLE_DEBUG_PRINTF // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!!
-#include <assert.h>
-
-#include <memory>
-
-#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Timer.h"
-
-#include "DWARFUnit.h"
-#include "LogChannelDWARF.h"
-#include "SymbolFileDWARF.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace std;
-
-// Parse
-//
-// Parse all information in the debug_line_data into an internal
-// representation.
-void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
- m_lineTableMap.clear();
- lldb::offset_t offset = 0;
- LineTable::shared_ptr line_table_sp(new LineTable);
- while (debug_line_data.ValidOffset(offset)) {
- const lldb::offset_t debug_line_offset = offset;
-
- if (line_table_sp.get() == nullptr)
- break;
-
- if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
- // Make sure we don't don't loop infinitely
- if (offset <= debug_line_offset)
- break;
- // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n",
- // debug_line_offset);
- m_lineTableMap[debug_line_offset] = line_table_sp;
- line_table_sp = std::make_shared<LineTable>();
- } else
- ++offset; // Try next byte in line table
- }
-}
-
-void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
- if (m_lineTableMap.empty())
- Parse(debug_line_data);
-}
-
-// DWARFDebugLine::GetLineTable
-DWARFDebugLine::LineTable::shared_ptr
-DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
- DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
- LineTableConstIter pos = m_lineTableMap.find(offset);
- if (pos != m_lineTableMap.end())
- line_table_shared_ptr = pos->second;
- return line_table_shared_ptr;
-}
-
-// Parse
-//
-// Parse the entire line table contents calling callback each time a new
-// prologue is parsed and every time a new row is to be added to the line
-// table.
-void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
- DWARFDebugLine::State::Callback callback,
- void *userData) {
- lldb::offset_t offset = 0;
- if (debug_line_data.ValidOffset(offset)) {
- if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr))
- ++offset; // Skip to next byte in .debug_line section
- }
-}
-
-namespace {
-struct EntryDescriptor {
- dw_sleb128_t code;
- dw_sleb128_t form;
-};
-
-static std::vector<EntryDescriptor>
-ReadDescriptors(const DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr) {
- std::vector<EntryDescriptor> ret;
- uint8_t n = debug_line_data.GetU8(offset_ptr);
- for (uint8_t i = 0; i < n; ++i) {
- EntryDescriptor ent;
- ent.code = debug_line_data.GetULEB128(offset_ptr);
- ent.form = debug_line_data.GetULEB128(offset_ptr);
- ret.push_back(ent);
- }
- return ret;
-}
-} // namespace
-
-// DWARFDebugLine::ParsePrologue
-bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr,
- Prologue *prologue, DWARFUnit *dwarf_cu) {
- const lldb::offset_t prologue_offset = *offset_ptr;
-
- // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
-
- prologue->Clear();
- uint32_t i;
- const char *s;
- prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
- prologue->version = debug_line_data.GetU16(offset_ptr);
- if (prologue->version < 2 || prologue->version > 5)
- return false;
-
- if (prologue->version >= 5) {
- prologue->address_size = debug_line_data.GetU8(offset_ptr);
- prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr);
- }
-
- prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
- const lldb::offset_t end_prologue_offset =
- prologue->prologue_length + *offset_ptr;
- prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
- if (prologue->version >= 4)
- prologue->maximum_operations_per_instruction =
- debug_line_data.GetU8(offset_ptr);
- else
- prologue->maximum_operations_per_instruction = 1;
- prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
- prologue->line_base = debug_line_data.GetU8(offset_ptr);
- prologue->line_range = debug_line_data.GetU8(offset_ptr);
- prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
-
- prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1);
-
- for (i = 1; i < prologue->opcode_base; ++i) {
- uint8_t op_len = debug_line_data.GetU8(offset_ptr);
- prologue->standard_opcode_lengths.push_back(op_len);
- }
-
- if (prologue->version >= 5) {
- std::vector<EntryDescriptor> dirEntryFormatV =
- ReadDescriptors(debug_line_data, offset_ptr);
- uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr);
- for (int i = 0; i < dirCount; ++i) {
- for (EntryDescriptor &ent : dirEntryFormatV) {
- DWARFFormValue value(dwarf_cu, ent.form);
- if (ent.code != DW_LNCT_path) {
- if (!value.SkipValue(debug_line_data, offset_ptr))
- return false;
- continue;
- }
-
- if (!value.ExtractValue(debug_line_data, offset_ptr))
- return false;
- prologue->include_directories.push_back(value.AsCString());
- }
- }
-
- std::vector<EntryDescriptor> filesEntryFormatV =
- ReadDescriptors(debug_line_data, offset_ptr);
- llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen;
- uint8_t n = debug_line_data.GetULEB128(offset_ptr);
- for (int i = 0; i < n; ++i) {
- FileNameEntry entry;
- for (EntryDescriptor &ent : filesEntryFormatV) {
- DWARFFormValue value(dwarf_cu, ent.form);
- if (!value.ExtractValue(debug_line_data, offset_ptr))
- return false;
-
- switch (ent.code) {
- case DW_LNCT_path:
- entry.name = value.AsCString();
- break;
- case DW_LNCT_directory_index:
- entry.dir_idx = value.Unsigned();
- break;
- case DW_LNCT_timestamp:
- entry.mod_time = value.Unsigned();
- break;
- case DW_LNCT_size:
- entry.length = value.Unsigned();
- break;
- case DW_LNCT_MD5:
- assert(value.Unsigned() == 16);
- std::uninitialized_copy_n(value.BlockData(), 16,
- entry.checksum.Bytes.begin());
- break;
- default:
- break;
- }
- }
-
- if (seen.insert(entry.checksum.words()).second)
- prologue->file_names.push_back(entry);
- }
- } else {
- while (*offset_ptr < end_prologue_offset) {
- s = debug_line_data.GetCStr(offset_ptr);
- if (s && s[0])
- prologue->include_directories.push_back(s);
- else
- break;
- }
-
- while (*offset_ptr < end_prologue_offset) {
- const char *name = debug_line_data.GetCStr(offset_ptr);
- if (name && name[0]) {
- FileNameEntry fileEntry;
- fileEntry.name = name;
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- prologue->file_names.push_back(fileEntry);
- } else
- break;
- }
- }
-
- // XXX GNU as is broken for 64-Bit DWARF
- if (*offset_ptr != end_prologue_offset) {
- Host::SystemLog(Host::eSystemLogWarning,
- "warning: parsing line table prologue at 0x%8.8" PRIx64
- " should have ended at 0x%8.8" PRIx64
- " but it ended at 0x%8.8" PRIx64 "\n",
- prologue_offset, end_prologue_offset, *offset_ptr);
- }
- return end_prologue_offset;
-}
-
-bool DWARFDebugLine::ParseSupportFiles(
- const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
- dw_offset_t stmt_list, FileSpecList &support_files, DWARFUnit *dwarf_cu) {
- lldb::offset_t offset = stmt_list;
-
- Prologue prologue;
- if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) {
- Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
- "at 0x%8.8x (parsing ended around "
- "0x%8.8" PRIx64 "\n",
- stmt_list, offset);
- return false;
- }
-
- FileSpec file_spec;
- std::string remapped_file;
-
- for (uint32_t file_idx = 1;
- prologue.GetFile(file_idx, dwarf_cu->GetCompilationDirectory(),
- dwarf_cu->GetPathStyle(), file_spec);
- ++file_idx) {
- if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
- file_spec.SetFile(remapped_file, FileSpec::Style::native);
- support_files.Append(file_spec);
- }
- return true;
-}
-
-// ParseStatementTable
-//
-// Parse a single line table (prologue and all rows) and call the callback
-// function once for the prologue (row in state will be zero) and each time a
-// row is to be added to the line table.
-bool DWARFDebugLine::ParseStatementTable(
- const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
- Prologue::shared_ptr prologue(new Prologue());
-
- const dw_offset_t debug_line_offset = *offset_ptr;
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
- debug_line_offset);
-
- if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) {
- if (log)
- log->Error("failed to parse DWARF line table prologue");
- // Restore our offset and return false to indicate failure!
- *offset_ptr = debug_line_offset;
- return false;
- }
-
- if (log)
- prologue->Dump(log);
-
- const dw_offset_t end_offset =
- debug_line_offset + prologue->total_length +
- (debug_line_data.GetDWARFSizeofInitialLength());
-
- State state(prologue, log, callback, userData);
-
- while (*offset_ptr < end_offset) {
- // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
- uint8_t opcode = debug_line_data.GetU8(offset_ptr);
-
- if (opcode == 0) {
- // Extended Opcodes always start with a zero opcode followed by a uleb128
- // length so you can skip ones you don't know about
- lldb::offset_t ext_offset = *offset_ptr;
- dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
- dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
-
- // DEBUG_PRINTF("Extended: <%2u> ", len);
- uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
- switch (sub_opcode) {
- case DW_LNE_end_sequence:
- // Set the end_sequence register of the state machine to true and
- // append a row to the matrix using the current values of the state-
- // machine registers. Then reset the registers to the initial values
- // specified above. Every statement program sequence must end with a
- // DW_LNE_end_sequence instruction which creates a row whose address is
- // that of the byte after the last target machine instruction of the
- // sequence.
- state.end_sequence = true;
- state.AppendRowToMatrix(*offset_ptr);
- state.Reset();
- break;
-
- case DW_LNE_set_address:
- // Takes a single relocatable address as an operand. The size of the
- // operand is the size appropriate to hold an address on the target
- // machine. Set the address register to the value given by the
- // relocatable address. All of the other statement program opcodes that
- // affect the address register add a delta to it. This instruction
- // stores a relocatable value into it instead.
- if (arg_size == 4)
- state.address = debug_line_data.GetU32(offset_ptr);
- else // arg_size == 8
- state.address = debug_line_data.GetU64(offset_ptr);
- break;
-
- case DW_LNE_define_file:
- // Takes 4 arguments. The first is a null terminated string containing
- // a source file name. The second is an unsigned LEB128 number
- // representing the directory index of the directory in which the file
- // was found. The third is an unsigned LEB128 number representing the
- // time of last modification of the file. The fourth is an unsigned
- // LEB128 number representing the length in bytes of the file. The time
- // and length fields may contain LEB128(0) if the information is not
- // available.
- //
- // The directory index represents an entry in the include_directories
- // section of the statement program prologue. The index is LEB128(0) if
- // the file was found in the current directory of the compilation,
- // LEB128(1) if it was found in the first directory in the
- // include_directories section, and so on. The directory index is
- // ignored for file names that represent full path names.
- //
- // The files are numbered, starting at 1, in the order in which they
- // appear; the names in the prologue come before names defined by the
- // DW_LNE_define_file instruction. These numbers are used in the file
- // register of the state machine.
- {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(offset_ptr);
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- state.prologue->file_names.push_back(fileEntry);
- }
- break;
-
- default:
- // Length doesn't include the zero opcode byte or the length itself,
- // but it does include the sub_opcode, so we have to adjust for that
- // below
- (*offset_ptr) += arg_size;
- break;
- }
- } else if (opcode < prologue->opcode_base) {
- switch (opcode) {
- // Standard Opcodes
- case DW_LNS_copy:
- // Takes no arguments. Append a row to the matrix using the current
- // values of the state-machine registers. Then set the basic_block
- // register to false.
- state.AppendRowToMatrix(*offset_ptr);
- break;
-
- case DW_LNS_advance_pc:
- // Takes a single unsigned LEB128 operand, multiplies it by the
- // min_inst_length field of the prologue, and adds the result to the
- // address register of the state machine.
- state.address +=
- debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
- break;
-
- case DW_LNS_advance_line:
- // Takes a single signed LEB128 operand and adds that value to the line
- // register of the state machine.
- state.line += debug_line_data.GetSLEB128(offset_ptr);
- break;
-
- case DW_LNS_set_file:
- // Takes a single unsigned LEB128 operand and stores it in the file
- // register of the state machine.
- state.file = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_set_column:
- // Takes a single unsigned LEB128 operand and stores it in the column
- // register of the state machine.
- state.column = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_negate_stmt:
- // Takes no arguments. Set the is_stmt register of the state machine to
- // the logical negation of its current value.
- state.is_stmt = !state.is_stmt;
- break;
-
- case DW_LNS_set_basic_block:
- // Takes no arguments. Set the basic_block register of the state
- // machine to true
- state.basic_block = true;
- break;
-
- case DW_LNS_const_add_pc:
- // Takes no arguments. Add to the address register of the state machine
- // the address increment value corresponding to special opcode 255. The
- // motivation for DW_LNS_const_add_pc is this: when the statement
- // program needs to advance the address by a small amount, it can use a
- // single special opcode, which occupies a single byte. When it needs
- // to advance the address by up to twice the range of the last special
- // opcode, it can use DW_LNS_const_add_pc followed by a special opcode,
- // for a total of two bytes. Only if it needs to advance the address by
- // more than twice that range will it need to use both
- // DW_LNS_advance_pc and a special opcode, requiring three or more
- // bytes.
- {
- uint8_t adjust_opcode = 255 - prologue->opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
- prologue->min_inst_length;
- state.address += addr_offset;
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- // Takes a single uhalf operand. Add to the address register of the
- // state machine the value of the (unencoded) operand. This is the only
- // extended opcode that takes an argument that is not a variable length
- // number. The motivation for DW_LNS_fixed_advance_pc is this: existing
- // assemblers cannot emit DW_LNS_advance_pc or special opcodes because
- // they cannot encode LEB128 numbers or judge when the computation of a
- // special opcode overflows and requires the use of DW_LNS_advance_pc.
- // Such assemblers, however, can use DW_LNS_fixed_advance_pc instead,
- // sacrificing compression.
- state.address += debug_line_data.GetU16(offset_ptr);
- break;
-
- case DW_LNS_set_prologue_end:
- // Takes no arguments. Set the prologue_end register of the state
- // machine to true
- state.prologue_end = true;
- break;
-
- case DW_LNS_set_epilogue_begin:
- // Takes no arguments. Set the basic_block register of the state
- // machine to true
- state.epilogue_begin = true;
- break;
-
- case DW_LNS_set_isa:
- // Takes a single unsigned LEB128 operand and stores it in the column
- // register of the state machine.
- state.isa = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- default:
- // Handle any unknown standard opcodes here. We know the lengths of
- // such opcodes because they are specified in the prologue as a
- // multiple of LEB128 operands for each opcode.
- {
- uint8_t i;
- assert(static_cast<size_t>(opcode - 1) <
- prologue->standard_opcode_lengths.size());
- const uint8_t opcode_length =
- prologue->standard_opcode_lengths[opcode - 1];
- for (i = 0; i < opcode_length; ++i)
- debug_line_data.Skip_LEB128(offset_ptr);
- }
- break;
- }
- } else {
- // Special Opcodes
-
- // A special opcode value is chosen based on the amount that needs
- // to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base field in
- // the header, plus the value of the line_range field, minus 1 (line base
- // + line range - 1). If the desired line increment is greater than the
- // maximum line increment, a standard opcode must be used instead of a
- // special opcode. The "address advance" is calculated by dividing the
- // desired address increment by the minimum_instruction_length field from
- // the header. The special opcode is then calculated using the following
- // formula:
- //
- // opcode = (desired line increment - line_base) + (line_range * address
- // advance) + opcode_base
- //
- // If the resulting opcode is greater than 255, a standard opcode must be
- // used instead.
- //
- // To decode a special opcode, subtract the opcode_base from the opcode
- // itself to give the adjusted opcode. The amount to increment the
- // address register is the result of the adjusted opcode divided by the
- // line_range multiplied by the minimum_instruction_length field from the
- // header. That is:
- //
- // address increment = (adjusted opcode / line_range) *
- // minimum_instruction_length
- //
- // The amount to increment the line register is the line_base plus the
- // result of the adjusted opcode modulo the line_range. That is:
- //
- // line increment = line_base + (adjusted opcode % line_range)
-
- uint8_t adjust_opcode = opcode - prologue->opcode_base;
- dw_addr_t addr_offset =
- (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
- int32_t line_offset =
- prologue->line_base + (adjust_opcode % prologue->line_range);
- state.line += line_offset;
- state.address += addr_offset;
- state.AppendRowToMatrix(*offset_ptr);
- }
- }
-
- state.Finalize(*offset_ptr);
-
- return end_offset;
-}
-
-// ParseStatementTableCallback
-static void ParseStatementTableCallback(dw_offset_t offset,
- const DWARFDebugLine::State &state,
- void *userData) {
- DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // Just started parsing the line table, so lets keep a reference to the
- // prologue using the supplied shared pointer
- line_table->prologue = state.prologue;
- } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
- // Done parsing line table, nothing to do for the cleanup
- } else {
- // We have a new row, lets append it
- line_table->AppendRow(state);
- }
-}
-
-// ParseStatementTable
-//
-// Parse a line table at offset and populate the LineTable class with the
-// prologue and all rows.
-bool DWARFDebugLine::ParseStatementTable(
- const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- LineTable *line_table, DWARFUnit *dwarf_cu) {
- return ParseStatementTable(debug_line_data, offset_ptr,
- ParseStatementTableCallback, line_table, dwarf_cu);
-}
-
-inline bool DWARFDebugLine::Prologue::IsValid() const {
- return SymbolFileDWARF::SupportedVersion(version);
-}
-
-// DWARFDebugLine::Prologue::Dump
-void DWARFDebugLine::Prologue::Dump(Log *log) {
- uint32_t i;
-
- log->Printf("Line table prologue:");
- log->Printf(" total_length: 0x%8.8x", total_length);
- log->Printf(" version: %u", version);
- log->Printf("prologue_length: 0x%8.8x", prologue_length);
- log->Printf("min_inst_length: %u", min_inst_length);
- log->Printf("default_is_stmt: %u", default_is_stmt);
- log->Printf(" line_base: %i", line_base);
- log->Printf(" line_range: %u", line_range);
- log->Printf(" opcode_base: %u", opcode_base);
-
- for (i = 0; i < standard_opcode_lengths.size(); ++i) {
- log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1),
- standard_opcode_lengths[i]);
- }
-
- if (!include_directories.empty()) {
- for (i = 0; i < include_directories.size(); ++i) {
- log->Printf("include_directories[%3u] = '%s'", i + 1,
- include_directories[i]);
- }
- }
-
- if (!file_names.empty()) {
- log->PutCString(" Dir Mod Time File Len File Name");
- log->PutCString(" ---- ---------- ---------- "
- "---------------------------");
- for (i = 0; i < file_names.size(); ++i) {
- const FileNameEntry &fileEntry = file_names[i];
- log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1,
- fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length,
- fileEntry.name);
- }
- }
-}
-
-// DWARFDebugLine::ParsePrologue::Append
-//
-// Append the contents of the prologue to the binary stream buffer
-// void
-// DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
-//{
-// uint32_t i;
-//
-// buff.Append32(total_length);
-// buff.Append16(version);
-// buff.Append32(prologue_length);
-// buff.Append8(min_inst_length);
-// buff.Append8(default_is_stmt);
-// buff.Append8(line_base);
-// buff.Append8(line_range);
-// buff.Append8(opcode_base);
-//
-// for (i=0; i<standard_opcode_lengths.size(); ++i)
-// buff.Append8(standard_opcode_lengths[i]);
-//
-// for (i=0; i<include_directories.size(); ++i)
-// buff.AppendCStr(include_directories[i].c_str());
-// buff.Append8(0); // Terminate the include directory section with empty
-// string
-//
-// for (i=0; i<file_names.size(); ++i)
-// {
-// buff.AppendCStr(file_names[i].name.c_str());
-// buff.Append32_as_ULEB128(file_names[i].dir_idx);
-// buff.Append32_as_ULEB128(file_names[i].mod_time);
-// buff.Append32_as_ULEB128(file_names[i].length);
-// }
-// buff.Append8(0); // Terminate the file names section with empty string
-//}
-
-bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
- const FileSpec &comp_dir,
- FileSpec::Style style,
- FileSpec &file) const {
- uint32_t idx = file_idx - 1; // File indexes are 1 based...
- if (idx < file_names.size()) {
- file.SetFile(file_names[idx].name, style);
- if (file.IsRelative()) {
- if (file_names[idx].dir_idx > 0) {
- const uint32_t dir_idx = file_names[idx].dir_idx - 1;
- if (dir_idx < include_directories.size()) {
- file.PrependPathComponent(include_directories[dir_idx]);
- if (!file.IsRelative())
- return true;
- }
- }
-
- if (comp_dir)
- file.PrependPathComponent(comp_dir);
- }
- return true;
- }
- return false;
-}
-
-void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
- rows.push_back(state);
-}
-
-// Compare function for the binary search in
-// DWARFDebugLine::LineTable::LookupAddress()
-static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
- const DWARFDebugLine::Row &row2) {
- return row1.address < row2.address;
-}
-
-// DWARFDebugLine::LineTable::LookupAddress
-uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
- dw_addr_t cu_high_pc) const {
- uint32_t index = UINT32_MAX;
- if (!rows.empty()) {
- // Use the lower_bound algorithm to perform a binary search since we know
- // that our line table data is ordered by address.
- DWARFDebugLine::Row row;
- row.address = address;
- Row::const_iterator begin_pos = rows.begin();
- Row::const_iterator end_pos = rows.end();
- Row::const_iterator pos =
- lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
- if (pos == end_pos) {
- if (address < cu_high_pc)
- return rows.size() - 1;
- } else {
- // Rely on fact that we are using a std::vector and we can do pointer
- // arithmetic to find the row index (which will be one less that what we
- // found since it will find the first position after the current address)
- // since std::vector iterators are just pointers to the container type.
- index = pos - begin_pos;
- if (pos->address > address) {
- if (index > 0)
- --index;
- else
- index = UINT32_MAX;
- }
- }
- }
- return index; // Failed to find address
-}
-
-// DWARFDebugLine::Row::Row
-DWARFDebugLine::Row::Row(bool default_is_stmt)
- : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
- basic_block(false), end_sequence(false), prologue_end(false),
- epilogue_begin(false), isa(0) {}
-
-// Called after a row is appended to the matrix
-void DWARFDebugLine::Row::PostAppend() {
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
-}
-
-// DWARFDebugLine::Row::Reset
-void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
- address = 0;
- line = 1;
- column = 0;
- file = 1;
- is_stmt = default_is_stmt;
- basic_block = false;
- end_sequence = false;
- prologue_end = false;
- epilogue_begin = false;
- isa = 0;
-}
-// DWARFDebugLine::Row::Dump
-void DWARFDebugLine::Row::Dump(Log *log) const {
- log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
- column, file, isa, is_stmt ? " is_stmt" : "",
- basic_block ? " basic_block" : "",
- prologue_end ? " prologue_end" : "",
- epilogue_begin ? " epilogue_begin" : "",
- end_sequence ? " end_sequence" : "");
-}
-
-// Compare function LineTable structures
-static bool AddressLessThan(const DWARFDebugLine::Row &a,
- const DWARFDebugLine::Row &b) {
- return a.address < b.address;
-}
-
-// Insert a row at the correct address if the addresses can be out of order
-// which can only happen when we are linking a line table that may have had
-// it's contents rearranged.
-void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
- const Row &state) {
- // If we don't have anything yet, or if the address of the last state in our
- // line table is less than the current one, just append the current state
- if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) {
- state_coll.push_back(state);
- } else {
- // Do a binary search for the correct entry
- pair<Row::iterator, Row::iterator> range(equal_range(
- state_coll.begin(), state_coll.end(), state, AddressLessThan));
-
- // If the addresses are equal, we can safely replace the previous entry
- // with the current one if the one it is replacing is an end_sequence
- // entry. We currently always place an extra end sequence when ever we exit
- // a valid address range for a function in case the functions get
- // rearranged by optimizations or by order specifications. These extra end
- // sequences will disappear by getting replaced with valid consecutive
- // entries within a compile unit if there are no gaps.
- if (range.first == range.second) {
- state_coll.insert(range.first, state);
- } else {
- if ((distance(range.first, range.second) == 1) &&
- range.first->end_sequence == true) {
- *range.first = state;
- } else {
- state_coll.insert(range.second, state);
- }
- }
- }
-}
-
-// DWARFDebugLine::State::State
-DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
- DWARFDebugLine::State::Callback cb, void *userData)
- : Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
- callbackUserData(userData), row(StartParsingLineTable) {
- // Call the callback with the initial row state of zero for the prologue
- if (callback)
- callback(0, *this, callbackUserData);
-}
-
-// DWARFDebugLine::State::Reset
-void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
-
-// DWARFDebugLine::State::AppendRowToMatrix
-void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
- // Each time we are to add an entry into the line table matrix call the
- // callback function so that someone can do something with the current state
- // of the state machine (like build a line table or dump the line table!)
- if (log) {
- if (row == 0) {
- log->PutCString("Address Line Column File ISA Flags");
- log->PutCString(
- "------------------ ------ ------ ------ --- -------------");
- }
- Dump(log);
- }
-
- ++row; // Increase the row number before we call our callback for a real row
- if (callback)
- callback(offset, *this, callbackUserData);
- PostAppend();
-}
-
-// DWARFDebugLine::State::Finalize
-void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
- // Call the callback with a special row state when we are done parsing a line
- // table
- row = DoneParsingLineTable;
- if (callback)
- callback(offset, *this, callbackUserData);
-}
-
-// void
-// DWARFDebugLine::AppendLineTableData
-//(
-// const DWARFDebugLine::Prologue* prologue,
-// const DWARFDebugLine::Row::collection& state_coll,
-// const uint32_t addr_size,
-// BinaryStreamBuf &debug_line_data
-//)
-//{
-// if (state_coll.empty())
-// {
-// // We have no entries, just make an empty line table
-// debug_line_data.Append8(0);
-// debug_line_data.Append8(1);
-// debug_line_data.Append8(DW_LNE_end_sequence);
-// }
-// else
-// {
-// DWARFDebugLine::Row::const_iterator pos;
-// Row::const_iterator end = state_coll.end();
-// bool default_is_stmt = prologue->default_is_stmt;
-// const DWARFDebugLine::Row reset_state(default_is_stmt);
-// const DWARFDebugLine::Row* prev_state = &reset_state;
-// const int32_t max_line_increment_for_special_opcode =
-// prologue->MaxLineIncrementForSpecialOpcode();
-// for (pos = state_coll.begin(); pos != end; ++pos)
-// {
-// const DWARFDebugLine::Row& curr_state = *pos;
-// int32_t line_increment = 0;
-// dw_addr_t addr_offset = curr_state.address - prev_state->address;
-// dw_addr_t addr_advance = (addr_offset) / prologue->min_inst_length;
-// line_increment = (int32_t)(curr_state.line - prev_state->line);
-//
-// // If our previous state was the reset state, then let's emit the
-// // address to keep GDB's DWARF parser happy. If we don't start each
-// // sequence with a DW_LNE_set_address opcode, the line table won't
-// // get slid properly in GDB.
-//
-// if (prev_state == &reset_state)
-// {
-// debug_line_data.Append8(0); // Extended opcode
-// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of
-// opcode bytes
-// debug_line_data.Append8(DW_LNE_set_address);
-// debug_line_data.AppendMax64(curr_state.address, addr_size);
-// addr_advance = 0;
-// }
-//
-// if (prev_state->file != curr_state.file)
-// {
-// debug_line_data.Append8(DW_LNS_set_file);
-// debug_line_data.Append32_as_ULEB128(curr_state.file);
-// }
-//
-// if (prev_state->column != curr_state.column)
-// {
-// debug_line_data.Append8(DW_LNS_set_column);
-// debug_line_data.Append32_as_ULEB128(curr_state.column);
-// }
-//
-// // Don't do anything fancy if we are at the end of a sequence
-// // as we don't want to push any extra rows since the
-// DW_LNE_end_sequence
-// // will push a row itself!
-// if (curr_state.end_sequence)
-// {
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Now push the end sequence on!
-// debug_line_data.Append8(0);
-// debug_line_data.Append8(1);
-// debug_line_data.Append8(DW_LNE_end_sequence);
-//
-// prev_state = &reset_state;
-// }
-// else
-// {
-// if (line_increment || addr_advance)
-// {
-// if (line_increment > max_line_increment_for_special_opcode)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// line_increment = 0;
-// }
-//
-// uint32_t special_opcode = (line_increment >=
-// prologue->line_base) ? ((line_increment -
-// prologue->line_base) + (prologue->line_range * addr_advance)
-// + prologue->opcode_base) : 256;
-// if (special_opcode > 255)
-// {
-// // Both the address and line won't fit in one special
-// opcode
-// // check to see if just the line advance will?
-// uint32_t special_opcode_line = ((line_increment >=
-// prologue->line_base) && (line_increment != 0)) ?
-// ((line_increment - prologue->line_base) +
-// prologue->opcode_base) : 256;
-//
-//
-// if (special_opcode_line > 255)
-// {
-// // Nope, the line advance won't fit by itself, check
-// the address increment by itself
-// uint32_t special_opcode_addr = addr_advance ?
-// ((0 - prologue->line_base) +
-// (prologue->line_range * addr_advance) +
-// prologue->opcode_base) : 256;
-//
-// if (special_opcode_addr > 255)
-// {
-// // Neither the address nor the line will fit in
-// a
-// // special opcode, we must manually enter both
-// then
-// // do a DW_LNS_copy to push a row (special
-// opcode
-// // automatically imply a new row is pushed)
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Now push a row onto the line table manually
-// debug_line_data.Append8(DW_LNS_copy);
-//
-// }
-// else
-// {
-// // The address increment alone will fit into a
-// special opcode
-// // so modify our line change, then issue a
-// special opcode
-// // for the address increment and it will push a
-// row into the
-// // line table
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// // Advance of line and address will fit into a
-// single byte special opcode
-// // and this will also push a row onto the line
-// table
-// debug_line_data.Append8(special_opcode_addr);
-// }
-// }
-// else
-// {
-// // The line change alone will fit into a special
-// opcode
-// // so modify our address increment first, then issue
-// a
-// // special opcode for the line change and it will
-// push
-// // a row into the line table
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Advance of line and address will fit into a
-// single byte special opcode
-// // and this will also push a row onto the line table
-// debug_line_data.Append8(special_opcode_line);
-// }
-// }
-// else
-// {
-// // Advance of line and address will fit into a single
-// byte special opcode
-// // and this will also push a row onto the line table
-// debug_line_data.Append8(special_opcode);
-// }
-// }
-// prev_state = &curr_state;
-// }
-// }
-// }
-//}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
deleted file mode 100644
index 0d236ca686b5..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ /dev/null
@@ -1,227 +0,0 @@
-//===-- DWARFDebugLine.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 SymbolFileDWARF_DWARFDebugLine_h_
-#define SymbolFileDWARF_DWARFDebugLine_h_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-private.h"
-
-#include "DWARFDataExtractor.h"
-#include "DWARFDefines.h"
-
-#include "llvm/Support/MD5.h"
-
-class DWARFUnit;
-class SymbolFileDWARF;
-
-// DWARFDebugLine
-class DWARFDebugLine {
-public:
- // FileNameEntry
- struct FileNameEntry {
- FileNameEntry()
- : name(nullptr), dir_idx(0), mod_time(0), length(0), checksum() {}
-
- const char *name;
- dw_sleb128_t dir_idx;
- dw_sleb128_t mod_time;
- dw_sleb128_t length;
- llvm::MD5::MD5Result checksum;
- };
-
- // Prologue
- struct Prologue {
-
- Prologue()
- : total_length(0), version(0), prologue_length(0), min_inst_length(0),
- default_is_stmt(0), line_base(0), line_range(0), opcode_base(0),
- standard_opcode_lengths(), include_directories(), file_names() {}
-
- typedef std::shared_ptr<Prologue> shared_ptr;
-
- uint32_t total_length; // The size in bytes of the statement information for
- // this compilation unit (not including the
- // total_length field itself).
- uint16_t
- version; // Version identifier for the statement information format.
-
- uint8_t address_size;
- uint8_t segment_selector_size;
-
- uint32_t prologue_length; // The number of bytes following the
- // prologue_length field to the beginning of the
- // first byte of the statement program itself.
- uint8_t min_inst_length; // The size in bytes of the smallest target machine
- // instruction. Statement program opcodes that
- // alter the address register first multiply their
- // operands by this value.
- uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum
- // number of individual
- // operations that may be
- // encoded in an instruction.
- uint8_t default_is_stmt; // The initial value of theis_stmtregister.
- int8_t line_base; // This parameter affects the meaning of the special
- // opcodes. See below.
- uint8_t line_range; // This parameter affects the meaning of the special
- // opcodes. See below.
- uint8_t opcode_base; // The number assigned to the first special opcode.
- std::vector<uint8_t> standard_opcode_lengths;
- std::vector<const char *> include_directories;
- std::vector<FileNameEntry> file_names;
-
- int32_t MaxLineIncrementForSpecialOpcode() const {
- return line_base + (int8_t)line_range - 1;
- }
- bool IsValid() const;
- // void Append(BinaryStreamBuf& buff) const;
- void Dump(lldb_private::Log *log);
- void Clear() {
- total_length = version = prologue_length = min_inst_length = line_base =
- line_range = opcode_base = 0;
- line_base = 0;
- standard_opcode_lengths.clear();
- include_directories.clear();
- file_names.clear();
- }
- bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir,
- lldb_private::FileSpec::Style style,
- lldb_private::FileSpec &file) const;
- };
-
- // Standard .debug_line state machine structure
- struct Row {
- typedef std::vector<Row> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- Row(bool default_is_stmt = false);
- virtual ~Row() {}
- void PostAppend();
- void Reset(bool default_is_stmt);
- void Dump(lldb_private::Log *log) const;
- static void Insert(Row::collection &state_coll, const Row &state);
-
- dw_addr_t address; // The program-counter value corresponding to a machine
- // instruction generated by the compiler.
- uint32_t line; // An unsigned integer indicating a source line number. Lines
- // are numbered beginning at 1. The compiler may emit the
- // value 0 in cases where an instruction cannot be attributed
- // to any source line.
- uint16_t column; // An unsigned integer indicating a column number within a
- // source line. Columns are numbered beginning at 1. The
- // value 0 is reserved to indicate that a statement begins
- // at the 'left edge' of the line.
- uint16_t file; // An unsigned integer indicating the identity of the source
- // file corresponding to a machine instruction.
- uint8_t is_stmt : 1, // A boolean indicating that the current instruction is
- // the beginning of a statement.
- basic_block : 1, // A boolean indicating that the current instruction is
- // the beginning of a basic block.
- end_sequence : 1, // A boolean indicating that the current address is
- // that of the first byte after the end of a sequence
- // of target machine instructions.
- prologue_end : 1, // A boolean indicating that the current address is
- // one (of possibly many) where execution should be
- // suspended for an entry breakpoint of a function.
- epilogue_begin : 1; // A boolean indicating that the current address is
- // one (of possibly many) where execution should be
- // suspended for an exit breakpoint of a function.
- uint32_t isa; // An unsigned integer whose value encodes the applicable
- // instruction set architecture for the current instruction.
- };
-
- // LineTable
- struct LineTable {
- typedef std::shared_ptr<LineTable> shared_ptr;
-
- LineTable() : prologue(), rows() {}
-
- void AppendRow(const DWARFDebugLine::Row &state);
- void Clear() {
- prologue.reset();
- rows.clear();
- }
-
- uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
-
- Prologue::shared_ptr prologue;
- Row::collection rows;
- };
-
- // State
- struct State : public Row {
- typedef void (*Callback)(dw_offset_t offset, const State &state,
- void *userData);
-
- // Special row codes used when calling the callback
- enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 };
-
- State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log,
- Callback callback, void *userData);
-
- void AppendRowToMatrix(dw_offset_t offset);
-
- void Finalize(dw_offset_t offset);
-
- void Reset();
-
- Prologue::shared_ptr prologue;
- lldb_private::Log *log;
- Callback callback; // Callback function that gets called each time an entry
- // is to be added to the matrix
- void *callbackUserData;
- int row; // The row number that starts at zero for the prologue, and
- // increases for each row added to the matrix
- private:
- DISALLOW_COPY_AND_ASSIGN(State);
- };
-
- static bool
- ParseSupportFiles(const lldb::ModuleSP &module_sp,
- const lldb_private::DWARFDataExtractor &debug_line_data,
- dw_offset_t stmt_list,
- lldb_private::FileSpecList &support_files,
- DWARFUnit *dwarf_cu);
- static bool
- ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, Prologue *prologue,
- DWARFUnit *dwarf_cu = nullptr);
- static bool
- ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, State::Callback callback,
- void *userData, DWARFUnit *dwarf_cu);
- static bool
- ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, LineTable *line_table,
- DWARFUnit *dwarf_cu);
- static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
- DWARFDebugLine::State::Callback callback, void *userData);
- // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
- // const DWARFDebugLine::Row::collection& state_coll, const uint32_t
- // addr_size, BinaryStreamBuf &debug_line_data);
-
- DWARFDebugLine() : m_lineTableMap() {}
-
- void Parse(const lldb_private::DWARFDataExtractor &debug_line_data);
- void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data);
- LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
-
-protected:
- typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
- typedef LineTableMap::iterator LineTableIter;
- typedef LineTableMap::const_iterator LineTableConstIter;
-
- LineTableMap m_lineTableMap;
-};
-
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 207c71211c9a..0b08fa09f906 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -123,11 +123,6 @@ bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
return false;
}
-uint64_t DWARFDebugRanges::GetOffset(size_t Index) const {
- lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5");
- return 0;
-}
-
bool DWARFDebugRngLists::ExtractRangeList(
const DWARFDataExtractor &data, uint8_t addrSize,
lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index baf2667f0afe..c398259056b3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -24,7 +24,6 @@ public:
virtual void Extract(lldb_private::DWARFContext &context) = 0;
virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const = 0;
- virtual uint64_t GetOffset(size_t Index) const = 0;
};
class DWARFDebugRanges final : public DWARFDebugRangesBase {
@@ -34,7 +33,6 @@ public:
void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
- uint64_t GetOffset(size_t Index) const override;
static void Dump(lldb_private::Stream &s,
const lldb_private::DWARFDataExtractor &debug_ranges_data,
@@ -62,7 +60,7 @@ public:
void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
- uint64_t GetOffset(size_t Index) const override;
+ uint64_t GetOffset(size_t Index) const;
protected:
bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index d0d70dd5123e..6501ac27f27d 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -23,7 +23,7 @@
class DWARFDeclContext {
public:
struct Entry {
- Entry() : tag(0), name(nullptr) {}
+ Entry() : tag(llvm::dwarf::DW_TAG_null), name(nullptr) {}
Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
bool NameMatches(const Entry &rhs) const {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 3bf0bb088227..2ae1bbc9f507 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -59,6 +59,8 @@ const char *DW_OP_value_to_name(uint32_t val) {
}
DRC_class DW_OP_value_to_class(uint32_t val) {
+ // FIXME: If we just used llvm's DWARFExpression printer, we could delete
+ // all this code (and more in lldb's DWARFExpression.cpp).
switch (val) {
case 0x03:
return DRC_ONEOPERAND;
@@ -358,6 +360,8 @@ DRC_class DW_OP_value_to_class(uint32_t val) {
return DRC_DWARFv3 | DRC_ONEOPERAND;
case 0x9a:
return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0xa3: /* DW_OP_entry_value */
+ return DRC_TWOOPERANDS;
case 0xf0:
return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
case 0xe0:
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 33e83d1fe57f..9964cf4b893c 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -438,7 +438,7 @@ lldb::ByteOrder DWARFUnit::GetByteOrder() const {
return m_dwarf.GetObjectFile()->GetByteOrder();
}
-TypeSystem *DWARFUnit::GetTypeSystem() {
+llvm::Expected<TypeSystem &> DWARFUnit::GetTypeSystem() {
return m_dwarf.GetTypeSystemForLanguage(GetLanguageType());
}
@@ -540,19 +540,15 @@ void DWARFUnit::ParseProducerInfo() {
} else if (strstr(producer_cstr, "clang")) {
static RegularExpression g_clang_version_regex(
llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"));
- RegularExpression::Match regex_match(3);
+ llvm::SmallVector<llvm::StringRef, 4> matches;
if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr),
- &regex_match)) {
- std::string str;
- if (regex_match.GetMatchAtIndex(producer_cstr, 1, str))
- m_producer_version_major =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 2, str))
- m_producer_version_minor =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 3, str))
- m_producer_version_update =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ &matches)) {
+ m_producer_version_major =
+ StringConvert::ToUInt32(matches[1].str().c_str(), UINT32_MAX, 10);
+ m_producer_version_minor =
+ StringConvert::ToUInt32(matches[2].str().c_str(), UINT32_MAX, 10);
+ m_producer_version_update =
+ StringConvert::ToUInt32(matches[3].str().c_str(), UINT32_MAX, 10);
}
m_producer = eProducerClang;
} else if (strstr(producer_cstr, "GNU"))
@@ -870,7 +866,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) const {
llvm::Expected<DWARFRangeList>
DWARFUnit::FindRnglistFromIndex(uint32_t index) const {
- const DWARFDebugRangesBase *debug_rnglists = m_dwarf.GetDebugRngLists();
+ const DWARFDebugRngLists *debug_rnglists = m_dwarf.GetDebugRngLists();
if (!debug_rnglists)
return llvm::make_error<llvm::object::GenericBinaryError>(
"No debug_rnglists section");
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 8aa1e449f3ed..87e0de283de4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -153,7 +153,7 @@ public:
lldb::ByteOrder GetByteOrder() const;
- lldb_private::TypeSystem *GetTypeSystem();
+ llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem();
const DWARFDebugAranges &GetFunctionAranges();
diff --git a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 9746ad76c930..007ef2e05e59 100644
--- a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -24,7 +24,7 @@ DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
return llvm::make_error<llvm::StringError>("debug info null",
llvm::inconvertibleErrorCode());
}
- auto index_up = llvm::make_unique<DebugNames>(debug_names.GetAsLLVM(),
+ auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(),
debug_str.GetAsLLVM());
if (llvm::Error E = index_up->extract())
return std::move(E);
@@ -105,7 +105,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
if (!regex.Execute(nte.getString()))
continue;
- uint32_t entry_offset = nte.getEntryOffset();
+ 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)) {
if (entry_or->tag() != DW_TAG_variable)
@@ -125,7 +125,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
uint64_t cu_offset = cu.GetOffset();
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
- uint32_t entry_offset = nte.getEntryOffset();
+ 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)) {
if (entry_or->tag() != DW_TAG_variable)
@@ -248,7 +248,7 @@ void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
if (!regex.Execute(nte.getString()))
continue;
- uint32_t entry_offset = nte.getEntryOffset();
+ 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)) {
Tag tag = entry_or->tag();
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 62b0ad37a9fc..88a29f4a2672 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -125,7 +125,7 @@ DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
: die_base_offset(_die_base_offset), atoms(), atom_mask(0),
min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
// Define an array of DIE offsets by first defining an array, and then define
- // the atom type for the array, in this case we have an array of DIE offsets
+ // the atom type for the array, in this case we have an array of DIE offsets.
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
}
@@ -208,9 +208,10 @@ DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
const uint32_t atom_count = data.GetU32(&offset);
if (atom_count == 0x00060003u) {
- // Old format, deal with contents of old pre-release format
- while (data.GetU32(&offset))
+ // Old format, deal with contents of old pre-release format.
+ while (data.GetU32(&offset)) {
/* do nothing */;
+ }
// Hardcode to the only known value for now.
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
@@ -226,7 +227,7 @@ DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
size_t DWARFMappedHash::Prologue::GetByteSize() const {
// Add an extra count to the atoms size for the zero termination Atom that
- // gets written to disk
+ // gets written to disk.
return sizeof(die_base_offset) + sizeof(uint32_t) +
atoms.size() * sizeof(Atom);
}
@@ -286,7 +287,7 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
break;
default:
- // We can always skip atoms we don't know about
+ // We can always skip atoms we don't know about.
break;
}
}
@@ -308,8 +309,8 @@ DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const {
bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset,
HashData &hash_data) const {
lldb::offset_t offset = hash_data_offset;
- offset += 4; // Skip string table offset that contains offset of hash name in
- // .debug_str
+ // Skip string table offset that contains offset of hash name in .debug_str.
+ offset += 4;
const uint32_t count = m_data.GetU32(&offset);
if (count > 0) {
hash_data.resize(count);
@@ -335,7 +336,7 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
return eResultEndOfHashData;
// There definitely should be a string for this string offset, if there
- // isn't, there is something wrong, return and error
+ // isn't, there is something wrong, return and error.
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == nullptr) {
*hash_data_offset_ptr = UINT32_MAX;
@@ -345,9 +346,8 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
const size_t min_total_hash_data_size =
count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 &&
- m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
- min_total_hash_data_size)) {
+ if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
// We have at least one HashData entry, and we have enough data to parse at
// least "count" HashData entries.
@@ -370,21 +370,22 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
if (match)
pair.value.push_back(die_info);
} else {
- // Something went wrong while reading the data
+ // Something went wrong while reading the data.
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
}
}
}
// Return the correct response depending on if the string matched or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup
- // results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will
- // get called
- // again for the next key/value or the key terminator which in our case is
- // a zero .debug_str offset.
+ if (match) {
+ // The key (cstring) matches and we have lookup results!
+ return eResultKeyMatch;
+ } else {
+ // The key doesn't match, this function will get called again for the
+ // next key/value or the key terminator which in our case is a zero
+ // .debug_str offset.
+ return eResultKeyMismatch;
+ }
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -402,7 +403,7 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
return eResultEndOfHashData;
// There definitely should be a string for this string offset, if there
- // isn't, there is something wrong, return and error
+ // isn't, there is something wrong, return and error.
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == nullptr)
return eResultError;
@@ -410,9 +411,8 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
const size_t min_total_hash_data_size =
count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 &&
- m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
- min_total_hash_data_size)) {
+ if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
const bool match = regex.Execute(llvm::StringRef(strp_cstr));
if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
@@ -438,14 +438,15 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
}
}
// Return the correct response depending on if the string matched or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup
- // results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will
- // get called
- // again for the next key/value or the key terminator which in our case is
- // a zero .debug_str offset.
+ if (match) {
+ // The key (cstring) matches and we have lookup results!
+ return eResultKeyMatch;
+ } else {
+ // The key doesn't match, this function will get called again for the
+ // next key/value or the key terminator which in our case is a zero
+ // .debug_str offset.
+ return eResultKeyMismatch;
+ }
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -466,7 +467,7 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
if (prev_hash_data_offset == hash_data_offset)
break;
- // Check the result of getting our hash data
+ // Check the result of getting our hash data.
switch (hash_result) {
case eResultKeyMatch:
case eResultKeyMismatch:
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index a01612b59528..56d9bc548877 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -24,37 +24,41 @@ class DWARFMappedHash {
public:
enum AtomType : uint16_t {
eAtomTypeNULL = 0u,
- eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
- eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that
- // contains the item in question
- eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1
- // (if no tags exceed 255) or DW_FORM_data2
- eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
- eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name
- // (since all hash entries are basename only)
- // For example a type like "std::vector<int>::iterator" would have a name of
- // "iterator"
- // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not
- // have to pull
- // in debug info for a type when we know the fully qualified name.
+ /// DIE offset, check form for encoding.
+ eAtomTypeDIEOffset = 1u,
+ /// DIE offset of the compiler unit header that contains the item in
+ /// question.
+ eAtomTypeCUOffset = 2u,
+ /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed
+ /// 255) or DW_FORM_data2.
+ eAtomTypeTag = 3u,
+ // Flags from enum NameFlags.
+ eAtomTypeNameFlags = 4u,
+ // Flags from enum TypeFlags.
+ eAtomTypeTypeFlags = 5u,
+ /// A 32 bit hash of the full qualified name (since all hash entries are
+ /// basename only) For example a type like "std::vector<int>::iterator"
+ /// would have a name of "iterator" and a 32 bit hash for
+ /// "std::vector<int>::iterator" to allow us to not have to pull in debug
+ /// info for a type when we know the fully qualified name.
+ eAtomTypeQualNameHash = 6u
};
- // Bit definitions for the eAtomTypeTypeFlags flags
+ /// Bit definitions for the eAtomTypeTypeFlags flags.
enum TypeFlags {
- // Always set for C++, only set for ObjC if this is the
- // @implementation for class
+ /// Always set for C++, only set for ObjC if this is the
+ /// @implementation for class.
eTypeFlagClassIsImplementation = (1u << 1)
};
struct DIEInfo {
dw_offset_t die_offset = DW_INVALID_OFFSET;
- dw_tag_t tag = 0;
+ dw_tag_t tag = llvm::dwarf::DW_TAG_null;
- /// Any flags for this DIEInfo
+ /// Any flags for this DIEInfo.
uint32_t type_flags = 0;
- /// A 32 bit hash of the fully qualified name
+ /// A 32 bit hash of the fully qualified name.
uint32_t qualified_name_hash = 0;
DIEInfo() = default;
@@ -94,7 +98,7 @@ public:
bool HashDataHasFixedByteSize() const;
- // DIE offset base so die offsets in hash_data can be CU relative
+ /// DIE offset base so die offsets in hash_data can be CU relative.
dw_offset_t die_base_offset;
AtomArray atoms;
uint32_t atom_mask;
@@ -113,8 +117,8 @@ public:
lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
};
- // A class for reading and using a saved hash table from a block of data
- // in memory
+ /// A class for reading and using a saved hash table from a block of data in
+ /// memory.
class MemoryTable
: public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header,
DIEInfoArray> {
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index e2ddcfc5d64b..c982d59c2830 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -8,6 +8,7 @@
#include "SymbolFileDWARF.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
@@ -43,7 +44,7 @@
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
@@ -58,7 +59,6 @@
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
-#include "DWARFDebugLine.h"
#include "DWARFDebugMacro.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
@@ -72,6 +72,7 @@
#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDwp.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Support/FileSystem.h"
#include <algorithm>
@@ -113,18 +114,12 @@ using namespace lldb_private;
namespace {
-static constexpr PropertyDefinition g_properties[] = {
- {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr,
- {},
- "If the DW_AT_comp_dir matches any of these paths the symbolic "
- "links will be resolved at DWARF parse time."},
- {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, {},
- "Ignore indexes present in the object files and always index DWARF "
- "manually."}};
+#define LLDB_PROPERTIES_symbolfiledwarf
+#include "SymbolFileDWARFProperties.inc"
enum {
- ePropertySymLinkPaths,
- ePropertyIgnoreIndexes,
+#define LLDB_PROPERTIES_symbolfiledwarf
+#include "SymbolFileDWARFPropertiesEnum.inc"
};
class PluginProperties : public Properties {
@@ -135,7 +130,7 @@ public:
PluginProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_symbolfiledwarf_properties);
}
FileSpecList GetSymLinkPaths() {
@@ -159,7 +154,66 @@ static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() {
return g_settings_sp;
}
-} // anonymous namespace end
+} // namespace
+
+static const llvm::DWARFDebugLine::LineTable *
+ParseLLVMLineTable(lldb_private::DWARFContext &context,
+ llvm::DWARFDebugLine &line, dw_offset_t line_offset,
+ dw_offset_t unit_offset) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+
+ llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM();
+ llvm::DWARFContext &ctx = context.GetAsLLVM();
+ llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =
+ line.getOrParseLineTable(
+ data, line_offset, ctx, nullptr, [&](llvm::Error e) {
+ LLDB_LOG_ERROR(log, std::move(e),
+ "SymbolFileDWARF::ParseLineTable failed to parse");
+ });
+
+ if (!line_table) {
+ LLDB_LOG_ERROR(log, line_table.takeError(),
+ "SymbolFileDWARF::ParseLineTable failed to parse");
+ return nullptr;
+ }
+ return *line_table;
+}
+
+static FileSpecList ParseSupportFilesFromPrologue(
+ const lldb::ModuleSP &module,
+ const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style,
+ llvm::StringRef compile_dir = {}, FileSpec first_file = {}) {
+ FileSpecList support_files;
+ support_files.Append(first_file);
+
+ const size_t number_of_files = prologue.FileNames.size();
+ for (size_t idx = 1; idx <= number_of_files; ++idx) {
+ std::string original_file;
+ if (!prologue.getFileNameByIndex(
+ idx, compile_dir,
+ llvm::DILineInfoSpecifier::FileLineInfoKind::Default, original_file,
+ style)) {
+ // Always add an entry so the indexes remain correct.
+ support_files.EmplaceBack();
+ continue;
+ }
+
+ std::string remapped_file;
+ if (!prologue.getFileNameByIndex(
+ idx, compile_dir,
+ llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+ remapped_file, style)) {
+ // Always add an entry so the indexes remain correct.
+ support_files.EmplaceBack(original_file, style);
+ continue;
+ }
+
+ module->RemapSourceFile(llvm::StringRef(original_file), remapped_file);
+ support_files.EmplaceBack(remapped_file, style);
+ }
+
+ return support_files;
+}
FileSpecList SymbolFileDWARF::GetSymlinkPaths() {
return GetGlobalPluginProperties()->GetSymLinkPaths();
@@ -197,20 +251,16 @@ const char *SymbolFileDWARF::GetPluginDescriptionStatic() {
return "DWARF and DWARF3 debug symbol file reader.";
}
-SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileDWARF(obj_file,
+SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileDWARF(std::move(objfile_sp),
/*dwo_section_list*/ nullptr);
}
-TypeList *SymbolFileDWARF::GetTypeList() {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
+TypeList &SymbolFileDWARF::GetTypeList() {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
return debug_map_symfile->GetTypeList();
- else
- return m_obj_file->GetModule()->GetTypeList();
+ return SymbolFile::GetTypeList();
}
void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
dw_offset_t max_die_offset, uint32_t type_mask,
@@ -264,6 +314,8 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
case DW_TAG_ptr_to_member_type:
add_type = (type_mask & eTypeClassMemberPointer) != 0;
break;
+ default:
+ break;
}
if (add_type) {
@@ -283,11 +335,11 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
}
}
-size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
- TypeClass type_mask, TypeList &type_list)
+void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
+ TypeClass type_mask, TypeList &type_list)
{
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
TypeSet type_set;
CompileUnit *comp_unit = nullptr;
@@ -297,8 +349,8 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
if (comp_unit) {
dwarf_cu = GetDWARFCompileUnit(comp_unit);
- if (dwarf_cu == nullptr)
- return 0;
+ if (!dwarf_cu)
+ return;
GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
dwarf_cu->GetNextUnitOffset(), type_mask, type_set);
} else {
@@ -315,16 +367,13 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
}
std::set<CompilerType> compiler_type_set;
- size_t num_types_added = 0;
for (Type *type : type_set) {
CompilerType compiler_type = type->GetForwardCompilerType();
if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
compiler_type_set.insert(compiler_type);
type_list.Insert(type->shared_from_this());
- ++num_types_added;
}
}
- return num_types_added;
}
// Gets the first parent that is a lexical block, function or inlined
@@ -342,19 +391,21 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block:
return die;
+ default:
+ break;
}
}
return DWARFDIE();
}
-SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile,
+SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
SectionList *dwo_section_list)
- : SymbolFile(objfile),
+ : SymbolFile(std::move(objfile_sp)),
UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to
// when this class parses .o files to
// contain the .o file index/ID
m_debug_map_module_wp(), m_debug_map_symfile(nullptr),
- m_context(objfile->GetModule()->GetSectionList(), dwo_section_list),
+ m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
m_data_debug_loc(), m_abbr(), m_info(), m_fetched_external_modules(false),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate),
m_unique_ast_type_map() {}
@@ -374,17 +425,17 @@ UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
return m_unique_ast_type_map;
}
-TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- TypeSystem *type_system;
- if (debug_map_symfile) {
- type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
- } else {
- type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
+llvm::Expected<TypeSystem &>
+SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
+ return debug_map_symfile->GetTypeSystemForLanguage(language);
+
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
}
- return type_system;
+ return type_system_or_err;
}
void SymbolFileDWARF::InitializeObject() {
@@ -420,7 +471,7 @@ void SymbolFileDWARF::InitializeObject() {
}
}
- m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
+ m_index = std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
DebugInfo());
}
@@ -430,9 +481,9 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
uint32_t SymbolFileDWARF::CalculateAbilities() {
uint32_t abilities = 0;
- if (m_obj_file != nullptr) {
+ if (m_objfile_sp != nullptr) {
const Section *section = nullptr;
- const SectionList *section_list = m_obj_file->GetSectionList();
+ const SectionList *section_list = m_objfile_sp->GetSectionList();
if (section_list == nullptr)
return 0;
@@ -462,10 +513,12 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
abbrev->GetUnsupportedForms(invalid_forms);
if (!invalid_forms.empty()) {
StreamString error;
- error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : "");
+ error.Printf("unsupported DW_FORM value%s:",
+ invalid_forms.size() > 1 ? "s" : "");
for (auto form : invalid_forms)
error.Printf(" %#x", form);
- m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str());
+ m_objfile_sp->GetModule()->ReportWarning(
+ "%s", error.GetString().str().c_str());
return 0;
}
}
@@ -477,10 +530,10 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
debug_line_file_size = section->GetFileSize();
} else {
const char *symfile_dir_cstr =
- m_obj_file->GetFileSpec().GetDirectory().GetCString();
+ m_objfile_sp->GetFileSpec().GetDirectory().GetCString();
if (symfile_dir_cstr) {
if (strcasestr(symfile_dir_cstr, ".dsym")) {
- if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) {
+ if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) {
// We have a dSYM file that didn't have a any debug info. If the
// string table has a size of 1, then it was made from an
// executable with no debug info, or from an executable that was
@@ -489,7 +542,7 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)
.get();
if (section && section->GetFileSize() == 1) {
- m_obj_file->GetModule()->ReportWarning(
+ m_objfile_sp->GetModule()->ReportWarning(
"empty dSYM file detected, dSYM was created with an "
"executable with no debug info.");
}
@@ -519,7 +572,7 @@ SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
- ModuleSP module_sp(m_obj_file->GetModule());
+ ModuleSP module_sp(m_objfile_sp->GetModule());
const SectionList *section_list = module_sp->GetSectionList();
if (!section_list)
return;
@@ -529,7 +582,7 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
return;
data.Clear();
- m_obj_file->ReadSectionData(section_sp.get(), data);
+ m_objfile_sp->ReadSectionData(section_sp.get(), data);
}
const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() {
@@ -556,7 +609,7 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (debug_abbrev_data.GetByteSize() == 0)
return nullptr;
- auto abbr = llvm::make_unique<DWARFDebugAbbrev>();
+ auto abbr = std::make_unique<DWARFDebugAbbrev>();
llvm::Error error = abbr->parse(debug_abbrev_data);
if (error) {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
@@ -579,7 +632,7 @@ DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0)
- m_info = llvm::make_unique<DWARFDebugInfo>(*this, m_context);
+ m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
}
return m_info.get();
}
@@ -604,7 +657,7 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
return nullptr;
}
-DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
+DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
if (!m_ranges) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
@@ -619,7 +672,7 @@ DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
return m_ranges.get();
}
-DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRngLists() {
+DWARFDebugRngLists *SymbolFileDWARF::GetDebugRngLists() {
if (!m_rnglists) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
@@ -648,7 +701,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
cu_sp = m_debug_map_symfile->GetCompileUnit(this);
dwarf_cu.SetUserData(cu_sp.get());
} else {
- ModuleSP module_sp(m_obj_file->GetModule());
+ ModuleSP module_sp(m_objfile_sp->GetModule());
if (module_sp) {
const DWARFDIE cu_die = dwarf_cu.DIE();
if (cu_die) {
@@ -677,8 +730,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
dwarf_cu.SetUserData(cu_sp.get());
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- dwarf_cu.GetID(), cu_sp);
+ SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);
}
}
}
@@ -715,7 +767,7 @@ llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
return m_lldb_cu_to_dwarf_unit[cu_idx];
}
-uint32_t SymbolFileDWARF::GetNumCompileUnits() {
+uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {
DWARFDebugInfo *info = DebugInfo();
if (!info)
return 0;
@@ -741,17 +793,21 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
const DWARFDIE &die) {
ASSERT_MODULE_LOCK(this);
- if (die.IsValid()) {
- TypeSystem *type_system =
- GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
-
- if (type_system) {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
- }
+ if (!die.IsValid())
+ return nullptr;
+
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse function");
+ return nullptr;
}
- return nullptr;
+ DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
+ if (!dwarf_ast)
+ return nullptr;
+
+ return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
}
bool SymbolFileDWARF::FixupAddress(Address &addr) {
@@ -763,7 +819,7 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) {
return true;
}
lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetLanguageType();
@@ -772,7 +828,7 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (!dwarf_cu)
return 0;
@@ -790,21 +846,23 @@ size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
return functions_added;
}
+void SymbolFileDWARF::ForEachExternalModule(
+ CompileUnit &comp_unit, llvm::function_ref<void(ModuleSP)> f) {
+ UpdateExternalModuleListIfNeeded();
+
+ for (auto &p : m_external_type_modules) {
+ ModuleSP module = p.second;
+ f(module);
+ for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i)
+ module->GetCompileUnitAtIndex(i)->ForEachExternalModule(f);
+ }
+}
+
bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
- ASSERT_MODULE_LOCK(this);
- if (DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit)) {
- const dw_offset_t stmt_list = unit->GetLineTableOffset();
- if (stmt_list != DW_INVALID_OFFSET) {
- // All file indexes in DWARF are one based and a file of index zero is
- // supposed to be the compile unit itself.
- support_files.Append(comp_unit);
- return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(),
- m_context.getOrLoadLineData(),
- stmt_list, support_files, unit);
- }
- }
- return false;
+ if (!comp_unit.GetLineTable())
+ ParseLineTable(comp_unit);
+ return true;
}
FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {
@@ -833,16 +891,26 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {
auto iter_bool = m_type_unit_support_files.try_emplace(offset);
FileSpecList &list = iter_bool.first->second;
if (iter_bool.second) {
- list.Append(FileSpec());
- DWARFDebugLine::ParseSupportFiles(GetObjectFile()->GetModule(),
- m_context.getOrLoadLineData(), offset,
- list, &tu);
+ uint64_t line_table_offset = offset;
+ llvm::DWARFDataExtractor data = m_context.getOrLoadLineData().GetAsLLVM();
+ llvm::DWARFContext &ctx = m_context.GetAsLLVM();
+ llvm::DWARFDebugLine::Prologue prologue;
+ llvm::Error error = prologue.parse(data, &line_table_offset, ctx);
+ if (error) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, std::move(error),
+ "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
+ "the line table prologue");
+ } else {
+ list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(),
+ prologue, tu.GetPathStyle());
+ }
}
return list;
}
bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetIsOptimized();
@@ -852,7 +920,7 @@ bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
bool SymbolFileDWARF::ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<SourceModule> &imported_modules) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
assert(sc.comp_unit);
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (!dwarf_cu)
@@ -901,102 +969,63 @@ bool SymbolFileDWARF::ParseImportedModules(
return true;
}
-struct ParseDWARFLineTableCallbackInfo {
- LineTable *line_table;
- std::unique_ptr<LineSequence> sequence_up;
- lldb::addr_t addr_mask;
-};
-
-// ParseStatementTableCallback
-static void ParseDWARFLineTableCallback(dw_offset_t offset,
- const DWARFDebugLine::State &state,
- void *userData) {
- if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // Just started parsing the line table
- } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
- // Done parsing line table, nothing to do for the cleanup
- } else {
- ParseDWARFLineTableCallbackInfo *info =
- (ParseDWARFLineTableCallbackInfo *)userData;
- LineTable *line_table = info->line_table;
-
- // If this is our first time here, we need to create a sequence container.
- if (!info->sequence_up) {
- info->sequence_up.reset(line_table->CreateLineSequenceContainer());
- assert(info->sequence_up.get());
- }
- line_table->AppendLineEntryToSequence(
- info->sequence_up.get(), state.address & info->addr_mask, state.line,
- state.column, state.file, state.is_stmt, state.basic_block,
- state.prologue_end, state.epilogue_begin, state.end_sequence);
- if (state.end_sequence) {
- // First, put the current sequence into the line table.
- line_table->InsertSequence(info->sequence_up.get());
- // Then, empty it to prepare for the next sequence.
- info->sequence_up->Clear();
- }
- }
-}
-
bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (comp_unit.GetLineTable() != nullptr)
return true;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
- if (dwarf_cu) {
- const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
- if (dwarf_cu_die) {
- const dw_offset_t cu_line_offset =
- dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list,
- DW_INVALID_OFFSET);
- if (cu_line_offset != DW_INVALID_OFFSET) {
- std::unique_ptr<LineTable> line_table_up(new LineTable(&comp_unit));
- if (line_table_up) {
- ParseDWARFLineTableCallbackInfo info;
- info.line_table = line_table_up.get();
-
- /*
- * MIPS:
- * The SymbolContext may not have a valid target, thus we may not be
- * able
- * to call Address::GetOpcodeLoadAddress() which would clear the bit
- * #0
- * for MIPS. Use ArchSpec to clear the bit #0.
- */
- switch (GetObjectFile()->GetArchitecture().GetMachine()) {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- info.addr_mask = ~((lldb::addr_t)1);
- break;
- default:
- info.addr_mask = ~((lldb::addr_t)0);
- break;
- }
+ if (!dwarf_cu)
+ return false;
- lldb::offset_t offset = cu_line_offset;
- DWARFDebugLine::ParseStatementTable(
- m_context.getOrLoadLineData(), &offset,
- ParseDWARFLineTableCallback, &info, dwarf_cu);
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We have an object file that has a line table with addresses that
- // are not linked. We need to link the line table and convert the
- // addresses that are relative to the .o file into addresses for
- // the main executable.
- comp_unit.SetLineTable(
- debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
- } else {
- comp_unit.SetLineTable(line_table_up.release());
- return true;
- }
- }
- }
+ const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
+ if (!dwarf_cu_die)
+ return false;
+
+ const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(
+ DW_AT_stmt_list, DW_INVALID_OFFSET);
+ if (cu_line_offset == DW_INVALID_OFFSET)
+ return false;
+
+ llvm::DWARFDebugLine line;
+ const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable(
+ m_context, line, cu_line_offset, dwarf_cu->GetOffset());
+
+ if (!line_table)
+ return false;
+
+ // FIXME: Rather than parsing the whole line table and then copying it over
+ // into LLDB, we should explore using a callback to populate the line table
+ // while we parse to reduce memory usage.
+ std::unique_ptr<LineTable> line_table_up =
+ std::make_unique<LineTable>(&comp_unit);
+ LineSequence *sequence = line_table_up->CreateLineSequenceContainer();
+ for (auto &row : line_table->Rows) {
+ line_table_up->AppendLineEntryToSequence(
+ sequence, row.Address.Address, row.Line, row.Column, row.File,
+ row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
+ row.EndSequence);
+ if (row.EndSequence) {
+ line_table_up->InsertSequence(sequence);
+ sequence = line_table_up->CreateLineSequenceContainer();
}
}
- return false;
+
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) {
+ // We have an object file that has a line table with addresses that are not
+ // linked. We need to link the line table and convert the addresses that
+ // are relative to the .o file into addresses for the main executable.
+ comp_unit.SetLineTable(
+ debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
+ } else {
+ comp_unit.SetLineTable(line_table_up.release());
+ }
+
+ comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue(
+ comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(),
+ dwarf_cu->GetCompilationDirectory().GetCString(), FileSpec(comp_unit)));
+
+ return true;
}
lldb_private::DebugMacrosSP
@@ -1022,7 +1051,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
}
bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu == nullptr)
@@ -1114,7 +1143,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
"0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64
") which has a base that is less than the function's low PC "
"0x%" PRIx64 ". Please file a bug and attach the file at the "
- "start of this error message",
+ "start of this error message",
block->GetID(), range_base, range.GetRangeEnd(),
subprogram_low_pc);
}
@@ -1188,15 +1217,10 @@ bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
}
void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
- TypeSystem *type_system = decl_ctx.GetTypeSystem();
- DWARFASTParser *ast_parser = type_system->GetDWARFParser();
- std::vector<DWARFDIE> decl_ctx_die_list =
- ast_parser->GetDIEForDeclContext(decl_ctx);
-
- for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
- for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl;
- decl = decl.GetSibling())
- ast_parser->GetDeclForUIDFromDWARF(decl);
+ auto *type_system = decl_ctx.GetTypeSystem();
+ if (type_system != nullptr)
+ type_system->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed(
+ decl_ctx);
}
user_id_t SymbolFileDWARF::GetUID(DIERef ref) {
@@ -1281,8 +1305,6 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
CompilerDeclContext
SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
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
@@ -1293,8 +1315,6 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
}
Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
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
@@ -1341,8 +1361,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
// Get the type, which could be a forward declaration
if (log)
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' "
- "resolve parent forward type for 0x%8.8x",
+ log,
+ "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' "
+ "resolve parent forward type for 0x%8.8x",
die.GetOffset(), die.GetTagAsCString(), die.GetName(),
decl_ctx_die.GetOffset());
} break;
@@ -1504,7 +1525,6 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
->GetDIE(die_ref);
}
-
DWARFDebugInfo *debug_info = DebugInfo();
if (debug_info)
return debug_info->GetDIE(die_ref);
@@ -1567,7 +1587,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (dwo_obj_file == nullptr)
return nullptr;
- return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
+ return std::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
}
void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
@@ -1607,7 +1627,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
}
}
dwo_module_spec.GetArchitecture() =
- m_obj_file->GetModule()->GetArchitecture();
+ m_objfile_sp->GetModule()->GetArchitecture();
// When LLDB loads "external" modules it looks at the presence of
// DW_AT_GNU_dwo_name. However, when the already created module
@@ -1621,8 +1641,8 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
// printed. However, as one can notice in this case we don't
// actually need to try to load the already loaded module
// (corresponding to .dwo) so we simply skip it.
- if (m_obj_file->GetFileSpec().GetFileNameExtension() == ".dwo" &&
- llvm::StringRef(m_obj_file->GetFileSpec().GetPath())
+ if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" &&
+ llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())
.endswith(dwo_module_spec.GetFileSpec().GetPath())) {
continue;
}
@@ -1694,6 +1714,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARF::"
@@ -1837,6 +1858,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
bool check_inlines,
SymbolContextItem resolve_scope,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint32_t prev_size = sc_list.GetSize();
if (resolve_scope & eSymbolContextCompUnit) {
for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
@@ -1849,7 +1871,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
bool file_spec_matches_cu_file_spec =
FileSpec::Equal(file_spec, *dc_cu, full_match);
if (check_inlines || file_spec_matches_cu_file_spec) {
- SymbolContext sc(m_obj_file->GetModule());
+ SymbolContext sc(m_objfile_sp->GetModule());
sc.comp_unit = dc_cu;
uint32_t file_idx = UINT32_MAX;
@@ -1961,9 +1983,16 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
}
TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
- TypeSystem *type_system = GetTypeSystemForLanguage(
+ auto type_system_or_err = GetTypeSystemForLanguage(
decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err),
+ "Unable to match namespace decl using TypeSystem");
+ return false;
+ }
+
+ if (decl_ctx_type_system == &type_system_or_err.get())
return true; // The type systems match, return true
// The namespace AST was valid, and it does not match...
@@ -1976,9 +2005,10 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
return false;
}
-uint32_t SymbolFileDWARF::FindGlobalVariables(
+void SymbolFileDWARF::FindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
@@ -1990,11 +2020,11 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
max_matches);
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
@@ -2012,7 +2042,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
const size_t num_die_matches = die_offsets.size();
if (num_die_matches) {
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
// Loop invariant: Variables up to this index have been checked for context
@@ -2081,12 +2111,12 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
name.GetCString(), static_cast<const void *>(parent_decl_ctx),
max_matches, num_matches);
}
- return num_matches;
}
-uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables) {
+void SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
+ uint32_t max_matches,
+ VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
@@ -2098,8 +2128,8 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
}
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
@@ -2108,7 +2138,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
m_index->GetGlobalVariables(regex, die_offsets);
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
const size_t num_matches = die_offsets.size();
@@ -2132,9 +2162,6 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
m_index->ReportInvalidDIERef(die_ref, regex.GetText());
}
}
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
@@ -2210,10 +2237,12 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
return false;
}
-uint32_t SymbolFileDWARF::FindFunctions(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARF::FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ FunctionNameType name_type_mask,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')",
name.AsCString());
@@ -2226,21 +2255,17 @@ uint32_t SymbolFileDWARF::FindFunctions(
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
- "name_type_mask=0x%x, append=%u, sc_list)",
- name.GetCString(), name_type_mask, append);
+ log,
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)",
+ name.GetCString(), name_type_mask);
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
// If name is empty then we won't find anything.
if (name.IsEmpty())
- return 0;
+ return;
// Remember how many sc_list are in the list before we search in case we are
// appending the results to a variable list.
@@ -2255,7 +2280,7 @@ uint32_t SymbolFileDWARF::FindFunctions(
std::vector<DWARFDIE> dies;
m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies);
- for (const DWARFDIE &die: dies) {
+ for (const DWARFDIE &die : dies) {
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
}
@@ -2265,18 +2290,18 @@ uint32_t SymbolFileDWARF::FindFunctions(
if (log && num_matches > 0) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
- "name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => "
- "%u",
- name.GetCString(), name_type_mask, include_inlines, append,
+ log,
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", "
+ "name_type_mask=0x%x, include_inlines=%d, sc_list) => %u",
+ name.GetCString(), name_type_mask, include_inlines,
num_matches);
}
- return num_matches;
}
-uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
@@ -2285,22 +2310,13 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
- regex.GetText().str().c_str(), append);
+ log, "SymbolFileDWARF::FindFunctions (regex=\"%s\", sc_list)",
+ regex.GetText().str().c_str());
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
DWARFDebugInfo *info = DebugInfo();
if (!info)
- return 0;
-
- // Remember how many sc_list are in the list before we search in case we are
- // appending the results to a variable list.
- uint32_t original_size = sc_list.GetSize();
+ return;
DIEArray offsets;
m_index->GetFunctions(regex, offsets);
@@ -2315,9 +2331,6 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
}
-
- // Return the number of variable that were appended to the list
- return sc_list.GetSize() - original_size;
}
void SymbolFileDWARF::GetMangledNamesForFunction(
@@ -2345,156 +2358,141 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
}
}
-uint32_t SymbolFileDWARF::FindTypes(
+void SymbolFileDWARF::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- types.Clear();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Make sure we haven't already searched this SymbolFile before...
if (searched_symbol_files.count(this))
- return 0;
- else
- searched_symbol_files.insert(this);
+ return;
+
+ searched_symbol_files.insert(this);
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
if (parent_decl_ctx)
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
- "%p (\"%s\"), append=%u, max_matches=%u, type_list)",
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "%p (\"%s\"), max_matches=%u, type_list)",
name.GetCString(), static_cast<const void *>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches);
+ parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches);
else
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
- "NULL, append=%u, max_matches=%u, type_list)",
- name.GetCString(), append, max_matches);
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "NULL, max_matches=%u, type_list)",
+ name.GetCString(), max_matches);
}
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
DIEArray die_offsets;
m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
- if (num_die_matches) {
- const uint32_t initial_types_size = types.GetSize();
- for (size_t i = 0; i < num_die_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
-
- if (die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- Type *matching_type = ResolveType(die, true, true);
- if (matching_type) {
- // We found a type pointer, now find the shared pointer form our type
- // list
- types.InsertUnique(matching_type->shared_from_this());
- if (types.GetSize() >= max_matches)
- break;
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- }
- }
- const uint32_t num_matches = types.GetSize() - initial_types_size;
- if (log && num_matches) {
- if (parent_decl_ctx) {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
- "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches,
- num_matches);
- } else {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
- "= NULL, append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(), append, max_matches, num_matches);
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ Type *matching_type = ResolveType(die, true, true);
+ if (matching_type) {
+ // We found a type pointer, now find the shared pointer form our type
+ // list
+ types.InsertUnique(matching_type->shared_from_this());
+ if (types.GetSize() >= max_matches)
+ break;
}
+ } else {
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
}
- return num_matches;
- } else {
+ }
+
+ // Next search through the reachable Clang modules. This only applies for
+ // DWARF objects compiled with -gmodules that haven't been processed by
+ // dsymutil.
+ if (num_die_matches < max_matches) {
UpdateExternalModuleListIfNeeded();
- for (const auto &pair : m_external_type_modules) {
- ModuleSP external_module_sp = pair.second;
- if (external_module_sp) {
- SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
- if (sym_vendor) {
- const uint32_t num_external_matches =
- sym_vendor->FindTypes(name, parent_decl_ctx, append, max_matches,
- searched_symbol_files, types);
- if (num_external_matches)
- return num_external_matches;
- }
- }
- }
+ 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);
}
- return 0;
+ if (log && types.GetSize()) {
+ if (parent_decl_ctx) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= %p (\"%s\"), max_matches=%u, type_list) => %u",
+ 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=\"%s\", parent_decl_ctx "
+ "= NULL, max_matches=%u, type_list) => %u",
+ name.GetCString(), max_matches, types.GetSize());
+ }
+ }
}
-size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- if (!append)
- types.Clear();
-
- if (context.empty())
- return 0;
+void SymbolFileDWARF::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (pattern.empty())
+ return;
- ConstString name = context.back().name;
+ ConstString name = pattern.back().name;
if (!name)
- return 0;
+ return;
DIEArray die_offsets;
m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
- if (num_die_matches) {
- size_t num_matches = 0;
- for (size_t i = 0; i < num_die_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
- if (die) {
- std::vector<CompilerContext> die_context;
- die.GetDeclContext(die_context);
- if (die_context != context)
- continue;
-
- Type *matching_type = ResolveType(die, true, true);
- if (matching_type) {
- // We found a type pointer, now find the shared pointer form our type
- // list
- types.InsertUnique(matching_type->shared_from_this());
- ++num_matches;
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- }
+ if (!die) {
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
+ continue;
}
- return num_matches;
+ if (!languages[die.GetCU()->GetLanguageType()])
+ continue;
+
+ llvm::SmallVector<CompilerContext, 4> die_context;
+ die.GetDeclContext(die_context);
+ if (!contextMatches(die_context, pattern))
+ continue;
+
+ 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 0;
}
CompilerDeclContext
SymbolFileDWARF::FindNamespace(ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
@@ -2536,8 +2534,9 @@ SymbolFileDWARF::FindNamespace(ConstString name,
}
if (log && namespace_decl_ctx) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
- "CompilerDeclContext(%p/%p) \"%s\"",
+ log,
+ "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
+ "CompilerDeclContext(%p/%p) \"%s\"",
name.GetCString(),
static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),
static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),
@@ -2632,11 +2631,10 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
return DWARFDIE();
}
-Symbol *
-SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
+Symbol *SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
Symbol *objc_class_symbol = nullptr;
- if (m_obj_file) {
- Symtab *symtab = m_obj_file->GetSymtab();
+ if (m_objfile_sp) {
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,
@@ -2653,8 +2651,7 @@ SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
// worry about the debug map
// DWARF file
// if we are doing darwin DWARF in .o file debugging.
-bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
- DWARFUnit *cu) {
+bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) {
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
@@ -2681,8 +2678,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, ConstString type_name,
- bool must_be_implementation) {
+ const DWARFDIE &die, ConstString type_name, bool must_be_implementation) {
TypeSP type_sp;
@@ -2727,7 +2723,7 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
" (cu 0x%8.8" PRIx64 ")\n",
die.GetID(),
- m_obj_file->GetFileSpec().GetFilename().AsCString(
+ m_objfile_sp->GetFileSpec().GetFilename().AsCString(
"<Unknown>"),
type_die.GetID(), type_cu->GetID());
@@ -2849,8 +2845,9 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
DWARF_LOG_LOOKUPS));
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
- "s, qualified-name='%s')",
+ log,
+ "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
+ "s, qualified-name='%s')",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName());
}
@@ -2863,10 +2860,18 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
// use this to ensure any matches we find are in a language that this
// type system supports
const LanguageType language = dwarf_decl_ctx.GetLanguage();
- TypeSystem *type_system = (language == eLanguageTypeUnknown)
- ? nullptr
- : GetTypeSystemForLanguage(language);
-
+ TypeSystem *type_system = nullptr;
+ if (language != eLanguageTypeUnknown) {
+ auto type_system_or_err = GetTypeSystemForLanguage(language);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Cannot get TypeSystem for language {}",
+ Language::GetNameForLanguageType(language));
+ } else {
+ type_system = &type_system_or_err.get();
+ }
+ }
if (num_matches) {
for (size_t i = 0; i < num_matches; ++i) {
const DIERef &die_ref = die_offsets[i];
@@ -2916,9 +2921,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::"
- "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
- "qualified-name='%s') trying die=0x%8.8x (%s)",
+ log,
+ "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') trying die=0x%8.8x (%s)",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
type_dwarf_decl_ctx.GetQualifiedName());
@@ -2937,9 +2943,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
std::string qualified_name;
type_die.GetQualifiedName(qualified_name);
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::"
- "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
- "qualified-name='%s') ignoring die=0x%8.8x (%s)",
+ log,
+ "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') ignoring die=0x%8.8x (%s)",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
qualified_name.c_str());
@@ -2960,21 +2967,21 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
if (!die)
return {};
- TypeSystem *type_system =
+ auto type_system_or_err =
GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
- if (!type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse type");
return {};
+ }
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
if (!dwarf_ast)
return {};
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
+ TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, type_is_new_ptr);
if (type_sp) {
- TypeList *type_list = GetTypeList();
- if (type_list)
- type_list->Insert(type_sp);
+ GetTypeList().Insert(type_sp);
if (die.Tag() == DW_TAG_subprogram) {
std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
@@ -2995,12 +3002,21 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
bool parse_siblings, bool parse_children) {
size_t types_added = 0;
DWARFDIE die = orig_die;
+
while (die) {
+ const dw_tag_t tag = die.Tag();
bool type_is_new = false;
- if (ParseType(sc, die, &type_is_new).get()) {
- if (type_is_new)
- ++types_added;
- }
+
+ Tag dwarf_tag = static_cast<Tag>(tag);
+
+ // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)
+ // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or
+ // not.
+ if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
+ ParseType(sc, die, &type_is_new);
+
+ if (type_is_new)
+ ++types_added;
if (parse_children && die.HasChildren()) {
if (die.Tag() == DW_TAG_subprogram) {
@@ -3020,7 +3036,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
}
size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompileUnit *comp_unit = func.GetCompileUnit();
lldbassert(comp_unit);
@@ -3040,7 +3056,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t types_added = 0;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu) {
@@ -3056,7 +3072,7 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (sc.comp_unit != nullptr) {
DWARFDebugInfo *info = DebugInfo();
if (info == nullptr)
@@ -3193,15 +3209,18 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(module, debug_info_data, die.GetCU(),
- block_offset, block_length);
+ location = DWARFExpression(
+ module,
+ DataExtractor(debug_info_data, block_offset, block_length),
+ die.GetCU());
} else if (DWARFFormValue::IsDataForm(form_value.Form())) {
// Retrieve the value as a data expression.
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
if (auto data_length = form_value.GetFixedSize())
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- data_offset, *data_length);
+ location = DWARFExpression(
+ module,
+ DataExtractor(debug_info_data, data_offset, *data_length),
+ die.GetCU());
else {
const uint8_t *data_pointer = form_value.BlockData();
if (data_pointer) {
@@ -3217,17 +3236,21 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (form_value.Form() == DW_FORM_strp) {
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
if (auto data_length = form_value.GetFixedSize())
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- data_offset, *data_length);
+ location = DWARFExpression(module,
+ DataExtractor(debug_info_data,
+ data_offset,
+ *data_length),
+ die.GetCU());
} else {
const char *str = form_value.AsCString();
uint32_t string_offset =
str - (const char *)debug_info_data.GetDataStart();
uint32_t string_length = strlen(str) + 1;
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- string_offset, string_length);
+ location = DWARFExpression(module,
+ DataExtractor(debug_info_data,
+ string_offset,
+ string_length),
+ die.GetCU());
}
}
}
@@ -3241,17 +3264,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(module, data, die.GetCU(),
- block_offset, block_length);
+ location = DWARFExpression(
+ module, DataExtractor(data, block_offset, block_length),
+ die.GetCU());
} else {
- const DWARFDataExtractor &debug_loc_data = DebugLocData();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(
- die.GetCU(), debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0) {
- location = DWARFExpression(module, debug_loc_data, die.GetCU(),
- debug_loc_offset, loc_list_length);
+ DataExtractor data = DebugLocData();
+ const dw_offset_t offset = form_value.Unsigned();
+ if (data.ValidOffset(offset)) {
+ data = DataExtractor(data, offset, data.GetByteSize() - offset);
+ location = DWARFExpression(module, data, die.GetCU());
assert(func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListSlide(
func_low_pc -
@@ -3522,6 +3543,8 @@ SymbolFileDWARF::FindBlockContainingSpecification(
spec_block_die_offset)
return die;
} break;
+ default:
+ break;
}
// Give the concrete function die specified by "func_die_offset", find the
@@ -3577,8 +3600,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
} else {
GetObjectFile()->GetModule()->ReportError(
"parent 0x%8.8" PRIx64 " %s with no valid compile unit in "
- "symbol context for 0x%8.8" PRIx64
- " %s.\n",
+ "symbol context for 0x%8.8" PRIx64 " %s.\n",
sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),
orig_die.GetID(), orig_die.GetTagAsCString());
}
@@ -3654,9 +3676,57 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
return vars_added;
}
+/// Collect call site parameters in a DW_TAG_call_site DIE.
+static CallSiteParameterArray
+CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
+ CallSiteParameterArray parameters;
+ for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid();
+ child = child.GetSibling()) {
+ if (child.Tag() != DW_TAG_call_site_parameter)
+ continue;
+
+ llvm::Optional<DWARFExpression> LocationInCallee = {};
+ llvm::Optional<DWARFExpression> LocationInCaller = {};
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = child.GetAttributes(attributes);
+
+ // Parse the location at index \p attr_index within this call site parameter
+ // DIE, or return None on failure.
+ auto parse_simple_location =
+ [&](int attr_index) -> llvm::Optional<DWARFExpression> {
+ DWARFFormValue form_value;
+ if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
+ return {};
+ if (!DWARFFormValue::IsBlockForm(form_value.Form()))
+ return {};
+ auto data = child.GetData();
+ uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ return DWARFExpression(module,
+ DataExtractor(data, block_offset, block_length),
+ child.GetCU());
+ };
+
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attr == DW_AT_location)
+ LocationInCallee = parse_simple_location(i);
+ if (attr == DW_AT_call_value)
+ LocationInCaller = parse_simple_location(i);
+ }
+
+ if (LocationInCallee && LocationInCaller) {
+ CallSiteParameter param = {*LocationInCallee, *LocationInCaller};
+ parameters.push_back(param);
+ }
+ }
+ return parameters;
+}
+
/// Collect call graph edges present in a function DIE.
static std::vector<lldb_private::CallEdge>
-CollectCallEdges(DWARFDIE function_die) {
+CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
// Check if the function has a supported call site-related attribute.
// TODO: In the future it may be worthwhile to support call_all_source_calls.
uint64_t has_call_edges =
@@ -3693,9 +3763,28 @@ CollectCallEdges(DWARFDIE function_die) {
addr_t return_pc = child.GetAttributeValueAsAddress(DW_AT_call_return_pc,
LLDB_INVALID_ADDRESS);
+ // Extract call site parameters.
+ CallSiteParameterArray parameters =
+ CollectCallSiteParameters(module, child);
+
LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})",
call_origin.GetPubname(), return_pc);
- call_edges.emplace_back(call_origin.GetMangledName(), return_pc);
+ if (log && parameters.size()) {
+ for (const CallSiteParameter &param : parameters) {
+ StreamString callee_loc_desc, caller_loc_desc;
+ param.LocationInCallee.GetDescription(&callee_loc_desc,
+ eDescriptionLevelBrief,
+ LLDB_INVALID_ADDRESS, nullptr);
+ param.LocationInCaller.GetDescription(&caller_loc_desc,
+ eDescriptionLevelBrief,
+ LLDB_INVALID_ADDRESS, nullptr);
+ LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}",
+ callee_loc_desc.GetString(), caller_loc_desc.GetString());
+ }
+ }
+
+ call_edges.emplace_back(call_origin.GetMangledName(), return_pc,
+ std::move(parameters));
}
return call_edges;
}
@@ -3704,7 +3793,7 @@ std::vector<lldb_private::CallEdge>
SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
DWARFDIE func_die = GetDIE(func_id.GetID());
if (func_die.IsValid())
- return CollectCallEdges(func_die);
+ return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
return {};
}
@@ -3713,11 +3802,17 @@ ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
-void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); }
+void SymbolFileDWARF::Dump(lldb_private::Stream &s) {
+ SymbolFile::Dump(s);
+ m_index->Dump(s);
+}
void SymbolFileDWARF::DumpClangAST(Stream &s) {
- TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
- ClangASTContext *clang = llvm::dyn_cast_or_null<ClangASTContext>(ts);
+ auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+ if (!ts_or_err)
+ return;
+ ClangASTContext *clang =
+ llvm::dyn_cast_or_null<ClangASTContext>(&ts_or_err.get());
if (!clang)
return;
clang->Dump(s);
@@ -3727,10 +3822,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
if (module_sp) {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor)
- m_debug_map_symfile =
- (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
+ m_debug_map_symfile =
+ (SymbolFileDWARFDebugMap *)module_sp->GetSymbolFile();
}
}
return m_debug_map_symfile;
@@ -3746,9 +3839,9 @@ SymbolFileDWARF::GetLocationListFormat() const {
SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
llvm::call_once(m_dwp_symfile_once_flag, [this]() {
ModuleSpec module_spec;
- module_spec.GetFileSpec() = m_obj_file->GetFileSpec();
+ module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
module_spec.GetSymbolFileSpec() =
- FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp");
+ FileSpec(m_objfile_sp->GetFileSpec().GetPath() + ".dwp");
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec dwp_filespec =
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 018af47305f4..04cb11d426be 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -46,7 +46,8 @@ class DWARFDebugAranges;
class DWARFDebugInfo;
class DWARFDebugInfoEntry;
class DWARFDebugLine;
-class DWARFDebugRangesBase;
+class DWARFDebugRanges;
+class DWARFDebugRngLists;
class DWARFDeclContext;
class DWARFFormValue;
class DWARFTypeUnit;
@@ -78,13 +79,13 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
static lldb_private::FileSpecList GetSymlinkPaths();
// Constructors and Destructors
- SymbolFileDWARF(lldb_private::ObjectFile *ofile,
+ SymbolFileDWARF(lldb::ObjectFileSP objfile_sp,
lldb_private::SectionList *dwo_section_list);
~SymbolFileDWARF() override;
@@ -95,10 +96,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -108,6 +105,10 @@ public:
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+ void
+ ForEachExternalModule(lldb_private::CompileUnit &comp_unit,
+ llvm::function_ref<void(lldb::ModuleSP)> f) override;
+
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
lldb_private::FileSpecList &support_files) override;
@@ -156,47 +157,46 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
void GetMangledNamesForFunction(
const std::string &scope_qualified_name,
std::vector<lldb_private::ConstString> &mangled_names) override;
- uint32_t
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
- size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
- bool append, lldb_private::TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
+ lldb_private::LanguageSet languages,
+ lldb_private::TypeMap &types) override;
- lldb_private::TypeList *GetTypeList() override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
-
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
@@ -223,8 +223,8 @@ public:
const DWARFDebugInfo *DebugInfo() const;
- DWARFDebugRangesBase *GetDebugRanges();
- DWARFDebugRangesBase *GetDebugRngLists();
+ DWARFDebugRanges *GetDebugRanges();
+ DWARFDebugRngLists *GetDebugRngLists();
const lldb_private::DWARFDataExtractor &DebugLocData();
@@ -331,6 +331,12 @@ protected:
bool DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx);
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
+ lldb_private::TypeList &GetTypeList() override;
+
virtual DWARFUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
@@ -477,8 +483,8 @@ protected:
typedef std::set<lldb::user_id_t> DIERefSet;
typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
NameToOffsetMap m_function_scope_qualified_name_map;
- std::unique_ptr<DWARFDebugRangesBase> m_ranges;
- std::unique_ptr<DWARFDebugRangesBase> m_rnglists;
+ std::unique_ptr<DWARFDebugRanges> m_ranges;
+ std::unique_ptr<DWARFDebugRngLists> m_rnglists;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
DIEToTypePtr m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 8ec64dbaf764..a50d4e460bae 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -41,7 +41,7 @@ using namespace lldb_private;
// Subclass lldb_private::Module so we can intercept the
// "Module::GetObjectFile()" (so we can fixup the object file sections) and
-// also for "Module::GetSymbolVendor()" (so we can fixup the symbol file id.
+// also for "Module::GetSymbolFile()" (so we can fixup the symbol file id.
const SymbolFileDWARFDebugMap::FileRangeMap &
SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
@@ -60,11 +60,11 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
return file_range_map;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- log->Printf(
- "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
- static_cast<void *>(this),
- oso_module->GetSpecificationDescription().c_str());
+ LLDB_LOGF(
+ log,
+ "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
+ static_cast<void *>(this),
+ oso_module->GetSpecificationDescription().c_str());
std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
@@ -173,12 +173,12 @@ public:
~DebugMapModule() override = default;
- SymbolVendor *
- GetSymbolVendor(bool can_create = true,
- lldb_private::Stream *feedback_strm = nullptr) override {
+ SymbolFile *
+ GetSymbolFile(bool can_create = true,
+ lldb_private::Stream *feedback_strm = nullptr) override {
// Scope for locker
if (m_symfile_up.get() || !can_create)
- return m_symfile_up.get();
+ return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
ModuleSP exe_module_sp(m_exe_module_wp.lock());
if (exe_module_sp) {
@@ -186,30 +186,28 @@ public:
ObjectFile *oso_objfile = GetObjectFile();
if (oso_objfile) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- SymbolVendor *symbol_vendor =
- Module::GetSymbolVendor(can_create, feedback_strm);
- if (symbol_vendor) {
+ if (SymbolFile *symfile =
+ Module::GetSymbolFile(can_create, feedback_strm)) {
// Set a pointer to this class to set our OSO DWARF file know that
// the DWARF is being used along with a debug map and that it will
// have the remapped sections that we do below.
SymbolFileDWARF *oso_symfile =
- SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
- symbol_vendor->GetSymbolFile());
+ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symfile);
if (!oso_symfile)
return nullptr;
ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
- SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
+ SymbolFile *exe_symfile = exe_module_sp->GetSymbolFile();
- if (exe_objfile && exe_sym_vendor) {
+ if (exe_objfile && exe_symfile) {
oso_symfile->SetDebugMapModule(exe_module_sp);
// Set the ID of the symbol file DWARF to the index of the OSO
// shifted left by 32 bits to provide a unique prefix for any
// UserID's that get created in the symbol file.
oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
}
- return symbol_vendor;
+ return symfile;
}
}
}
@@ -239,13 +237,13 @@ const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
return "DWARF and DWARF3 debug symbol file reader (debug map).";
}
-SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileDWARFDebugMap(obj_file);
+SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileDWARFDebugMap(std::move(objfile_sp));
}
-SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
- : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
- m_glob_indexes(),
+SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(),
+ m_func_indexes(), m_glob_indexes(),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
@@ -260,12 +258,12 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// If the object file has been stripped, there is no sense in looking further
// as all of the debug symbols for the debug map will not be available
- if (m_obj_file->IsStripped())
+ if (m_objfile_sp->IsStripped())
return;
// Also make sure the file type is some sort of executable. Core files, debug
// info files (dSYM), object files (.o files), and stub libraries all can
- switch (m_obj_file->GetType()) {
+ switch (m_objfile_sp->GetType()) {
case ObjectFile::eTypeInvalid:
case ObjectFile::eTypeCoreFile:
case ObjectFile::eTypeDebugInfo:
@@ -286,7 +284,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// these files exist and also contain valid DWARF. If we get any of that then
// we return the abilities of the first N_OSO's DWARF.
- Symtab *symtab = m_obj_file->GetSymtab();
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
@@ -352,7 +350,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// The sibling index can't be less that or equal to the current index
// "i"
if (sibling_idx == UINT32_MAX) {
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO in symbol with UID %u has invalid sibling in debug map, "
"please file a bug and attach the binary listed in this error",
so_symbol->GetID());
@@ -363,28 +361,27 @@ void SymbolFileDWARFDebugMap::InitOSO() {
m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
- if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
- oso_symbol->GetName().GetCString());
+ LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i,
+ oso_symbol->GetName().GetCString());
}
} else {
if (oso_symbol == nullptr)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_OSO symbol[%u] can't be found, please file a bug and attach "
"the binary listed in this error",
oso_idx);
else if (so_symbol == nullptr)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO not found for N_OSO symbol[%u], please file a bug and "
"attach the binary listed in this error",
oso_idx);
else if (so_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
"please file a bug and attach the binary listed in this error",
so_symbol->GetType(), oso_idx);
else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
"please file a bug and attach the binary listed in this error",
oso_symbol->GetType(), oso_idx);
@@ -421,7 +418,11 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
// than the one from the CU.
auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
FileSystem::Instance().GetModificationTime(oso_file));
- if (oso_mod_time != comp_unit_info->oso_mod_time) {
+ // A timestamp of 0 means that the linker was in deterministic mode. In
+ // that case, we should skip the check against the filesystem last
+ // modification timestamp, since it will never match.
+ if (comp_unit_info->oso_mod_time != llvm::sys::TimePoint<>() &&
+ oso_mod_time != comp_unit_info->oso_mod_time) {
obj_file->GetModule()->ReportError(
"debug map object file '%s' has changed (actual time is "
"%s, debug map time is %s"
@@ -448,7 +449,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
// since .o files for "i386-apple-ios" will historically show up as "i386
// -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
// LC_VERSION_MIN_IPHONEOS load command...
- oso_arch.SetTriple(m_obj_file->GetModule()
+ oso_arch.SetTriple(m_objfile_sp->GetModule()
->GetArchitecture()
.GetTriple()
.getArchName()
@@ -534,12 +535,8 @@ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
CompileUnitInfo *comp_unit_info) {
- Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
- if (oso_module) {
- SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
- if (sym_vendor)
- return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
- }
+ if (Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info))
+ return GetSymbolFileAsSymbolFileDWARF(oso_module->GetSymbolFile());
return nullptr;
}
@@ -562,7 +559,7 @@ uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
return 0;
}
-uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
+uint32_t SymbolFileDWARFDebugMap::CalculateNumCompileUnits() {
InitOSO();
return m_compile_unit_infos.size();
}
@@ -581,13 +578,12 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
lldb::user_id_t cu_id = 0;
m_compile_unit_infos[cu_idx].compile_unit_sp =
std::make_shared<CompileUnit>(
- m_obj_file->GetModule(), nullptr, so_file_spec, cu_id,
+ m_objfile_sp->GetModule(), nullptr, so_file_spec, cu_id,
eLanguageTypeUnknown, eLazyBoolCalculate);
if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
- // Let our symbol vendor know about this compile unit
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
+ SetCompileUnitAtIndex(cu_idx,
+ m_compile_unit_infos[cu_idx].compile_unit_sp);
}
}
}
@@ -625,6 +621,7 @@ size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
lldb::LanguageType
SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseLanguage(comp_unit);
@@ -632,6 +629,7 @@ SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseFunctions(comp_unit);
@@ -639,6 +637,7 @@ size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseLineTable(comp_unit);
@@ -646,14 +645,24 @@ bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
}
bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseDebugMacros(comp_unit);
return false;
}
+void SymbolFileDWARFDebugMap::ForEachExternalModule(
+ CompileUnit &comp_unit, llvm::function_ref<void(ModuleSP)> f) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
+ if (oso_dwarf)
+ oso_dwarf->ForEachExternalModule(comp_unit, f);
+}
+
bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
@@ -661,6 +670,7 @@ bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
}
bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseIsOptimized(comp_unit);
@@ -669,6 +679,7 @@ bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
bool SymbolFileDWARFDebugMap::ParseImportedModules(
const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
if (oso_dwarf)
return oso_dwarf->ParseImportedModules(sc, imported_modules);
@@ -676,6 +687,7 @@ bool SymbolFileDWARFDebugMap::ParseImportedModules(
}
size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompileUnit *comp_unit = func.GetCompileUnit();
if (!comp_unit)
return 0;
@@ -687,6 +699,7 @@ size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseTypes(comp_unit);
@@ -695,6 +708,7 @@ size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
size_t
SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
if (oso_dwarf)
return oso_dwarf->ParseVariablesForContext(sc);
@@ -702,6 +716,7 @@ SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
}
Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf)
@@ -738,8 +753,9 @@ uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
- Symtab *symtab = m_obj_file->GetSymtab();
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
@@ -766,7 +782,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
Address oso_so_addr;
if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
resolved_flags |=
- oso_module->GetSymbolVendor()->ResolveSymbolContext(
+ oso_module->GetSymbolFile()->ResolveSymbolContext(
oso_so_addr, resolve_scope, sc);
}
}
@@ -780,6 +796,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint32_t initial = sc_list.GetSize();
const uint32_t cu_count = GetNumCompileUnits();
@@ -807,12 +824,11 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
return sc_list.GetSize() - initial;
}
-uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
+void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
const std::vector<uint32_t>
&indexes, // Indexes into the symbol table that match "name"
uint32_t max_matches, VariableList &variables) {
- const uint32_t original_size = variables.GetSize();
const size_t match_count = indexes.size();
for (size_t i = 0; i < match_count; ++i) {
uint32_t oso_idx;
@@ -821,28 +837,26 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
if (comp_unit_info) {
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf) {
- if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
- variables))
- if (variables.GetSize() > max_matches)
- break;
+ oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
+ if (variables.GetSize() > max_matches)
+ break;
}
}
}
- return variables.GetSize() - original_size;
}
-uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
+void SymbolFileDWARFDebugMap::FindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
-
- // Remember how many variables are in the list before we search.
- const uint32_t original_size = variables.GetSize();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
- name, parent_decl_ctx, max_matches, variables);
+ const uint32_t old_size = variables.GetSize();
+ oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
+ const uint32_t oso_matches = variables.GetSize() - old_size;
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -861,22 +875,18 @@ uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
return false;
});
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables) {
- // Remember how many variables are in the list before we search.
- const uint32_t original_size = variables.GetSize();
-
+void SymbolFileDWARFDebugMap::FindGlobalVariables(
+ const RegularExpression &regex, uint32_t max_matches,
+ VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches =
- oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
+ const uint32_t old_size = variables.GetSize();
+ oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
+
+ const uint32_t oso_matches = variables.GetSize() - old_size;
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -895,9 +905,6 @@ SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
return false;
});
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
@@ -993,71 +1000,58 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
}
}
-uint32_t SymbolFileDWARFDebugMap::FindFunctions(
+void SymbolFileDWARFDebugMap::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
name.GetCString());
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
-
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
- include_inlines, true, sc_list)) {
- RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
+ include_inlines, sc_list);
+ if (!sc_list.IsEmpty()) {
+ RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
});
-
- return sc_list.GetSize() - initial_size;
}
-uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
- bool include_inlines,
- bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
-
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) {
- RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ oso_dwarf->FindFunctions(regex, include_inlines, sc_list);
+ if (!sc_list.IsEmpty()) {
+ RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
});
-
- return sc_list.GetSize() - initial_size;
}
-size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- TypeList &type_list) {
+void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ TypeList &type_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
type_mask);
- uint32_t initial_size = type_list.GetSize();
SymbolFileDWARF *oso_dwarf = nullptr;
if (sc_scope) {
SymbolContext sc;
@@ -1075,7 +1069,6 @@ size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
return false;
});
}
- return type_list.GetSize() - initial_size;
}
std::vector<lldb_private::CallEdge>
@@ -1124,7 +1117,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
// N_SO.
SymbolFileDWARF *oso_dwarf = nullptr;
TypeSP type_sp;
- ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
+ ObjectFile *module_objfile = m_objfile_sp->GetModule()->GetObjectFile();
if (module_objfile) {
Symtab *symtab = module_objfile->GetSymtab();
if (symtab) {
@@ -1177,23 +1170,17 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
return TypeSP();
}
-uint32_t SymbolFileDWARFDebugMap::FindTypes(
+void SymbolFileDWARFDebugMap::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- if (!append)
- types.Clear();
-
- const uint32_t initial_types_size = types.GetSize();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches,
+ oso_dwarf->FindTypes(name, parent_decl_ctx, max_matches,
searched_symbol_files, types);
return types.GetSize() >= max_matches;
});
-
- return types.GetSize() - initial_types_size;
}
//
@@ -1212,6 +1199,7 @@ uint32_t SymbolFileDWARFDebugMap::FindTypes(
CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
lldb_private::ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompilerDeclContext matching_namespace;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
@@ -1284,8 +1272,7 @@ void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
cu_sp.get());
} else {
m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, cu_sp);
+ SetCompileUnitAtIndex(cu_idx, cu_sp);
}
}
}
@@ -1388,8 +1375,8 @@ bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
if (addr_module == exe_module)
return true; // Address is already in terms of the main executable module
- CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF(
- addr_module->GetSymbolVendor()->GetSymbolFile()));
+ CompileUnitInfo *cu_info = GetCompileUnitInfo(
+ GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolFile()));
if (cu_info) {
const lldb::addr_t oso_file_addr = addr.GetFileAddress();
const FileRangeMap::Entry *oso_range_entry =
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index afc6142e8231..7adee1b356ce 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -34,19 +34,16 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFileDWARFDebugMap(lldb_private::ObjectFile *ofile);
+ SymbolFileDWARFDebugMap(lldb::ObjectFileSP objfile_sp);
~SymbolFileDWARFDebugMap() override;
uint32_t CalculateAbilities() override;
void InitializeObject() override;
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -56,6 +53,10 @@ public:
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+ void
+ ForEachExternalModule(lldb_private::CompileUnit &comp_unit,
+ llvm::function_ref<void(lldb::ModuleSP)> f) override;
+
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
lldb_private::FileSpecList &support_files) override;
@@ -91,34 +92,34 @@ public:
bool check_inlines,
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ 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,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
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) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
std::vector<lldb_private::CallEdge>
ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
@@ -174,6 +175,9 @@ protected:
// Protected Member Functions
void InitOSO();
+ uint32_t CalculateNumCompileUnits() override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
return (uint32_t)((uid >> 32ull) - 1ull);
}
@@ -232,7 +236,7 @@ protected:
static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
const CompileUnitInfo *comp_unit_info);
- uint32_t PrivateFindGlobalVariables(
+ 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,
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index c5b54b65ea29..b0f7e813d4f8 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -23,21 +23,21 @@ using namespace lldb_private;
SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
DWARFCompileUnit &dwarf_cu)
- : SymbolFileDWARF(objfile.get(), objfile->GetSectionList(
- /*update_module_section_list*/ false)),
- m_obj_file_sp(objfile), m_base_dwarf_cu(dwarf_cu) {
+ : SymbolFileDWARF(objfile, objfile->GetSectionList(
+ /*update_module_section_list*/ false)),
+ m_base_dwarf_cu(dwarf_cu) {
SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32);
}
void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
const SectionList *section_list =
- m_obj_file->GetSectionList(false /* update_module_section_list */);
+ m_objfile_sp->GetSectionList(false /* update_module_section_list */);
if (section_list) {
SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
if (section_sp) {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+ if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0)
return;
data.Clear();
@@ -140,7 +140,7 @@ SymbolFileDWARFDwo::GetLocationListFormat() const {
return DWARFExpression::SplitDwarfLocationList;
}
-TypeSystem *
+llvm::Expected<TypeSystem &>
SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 9b2f3bb84c4f..ad290cdcf65e 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -30,7 +30,7 @@ public:
size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
DIEArray &method_die_offsets) override;
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
DWARFDIE
@@ -71,7 +71,6 @@ protected:
DWARFCompileUnit *ComputeCompileUnit();
- lldb::ObjectFileSP m_obj_file_sp;
DWARFCompileUnit &m_base_dwarf_cu;
DWARFCompileUnit *m_cu = nullptr;
};
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
new file mode 100644
index 000000000000..ef6ae3498588
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
@@ -0,0 +1,12 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "symbolfiledwarf" in {
+ def SymLinkPaths: Property<"comp-dir-symlink-paths", "FileSpecList">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time.">;
+ def IgnoreIndexes: Property<"ignore-file-indexes", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Ignore indexes present in the object files and always index DWARF manually.">;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 8da7e2226266..4862fea8d079 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -55,6 +55,8 @@ bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
case DW_TAG_partial_unit:
done = true;
break;
+ default:
+ break;
}
}
parent_arg_die = parent_arg_die.GetParent();
diff --git a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index 1838204e4ca6..830d78f81679 100644
--- a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -130,7 +130,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
if (!stream_data) {
llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, nullptr);
- cci = llvm::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
+ cci = std::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
return *cci;
}
@@ -139,7 +139,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
cantFail(debug_stream.reload());
- cci = llvm::make_unique<CompilandIndexItem>(
+ cci = std::make_unique<CompilandIndexItem>(
PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor));
ParseExtendedInfo(m_index, *cci);
diff --git a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 3d8bfb058721..6aaff06cc134 100644
--- a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -122,7 +122,7 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ DWARFExpression result(module, extractor, nullptr);
result.SetRegisterKind(register_kind);
return result;
@@ -247,6 +247,6 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
.take_front(size);
buffer->CopyData(bytes.data(), size);
DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
- DWARFExpression result(nullptr, extractor, nullptr, 0, size);
+ DWARFExpression result(nullptr, extractor, nullptr);
return result;
}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 4991be8e70ce..986b0b785d87 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -121,13 +121,6 @@ AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {
return false;
}
-static ClangASTContext &GetClangASTContext(ObjectFile &obj) {
- TypeSystem *ts =
- obj.GetModule()->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- lldbassert(ts);
- return static_cast<ClangASTContext &>(*ts);
-}
-
static llvm::Optional<clang::CallingConv>
TranslateCallingConvention(llvm::codeview::CallingConvention conv) {
using CC = llvm::codeview::CallingConvention;
@@ -209,8 +202,8 @@ static bool IsAnonymousNamespaceName(llvm::StringRef name) {
return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
}
-PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
- : m_index(index), m_clang(GetClangASTContext(obj)) {
+PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang)
+ : m_index(index), m_clang(clang) {
BuildParentMap();
}
@@ -465,9 +458,9 @@ clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
}
}
-clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
+llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
if (clang::Decl *result = TryGetDecl(uid))
- return result;
+ return ToCompilerDecl(*result);
clang::Decl *result = nullptr;
switch (uid.kind()) {
@@ -480,13 +473,13 @@ clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
result = tag;
break;
}
- return nullptr;
+ return llvm::None;
}
default:
- return nullptr;
+ return llvm::None;
}
m_uid_to_decl[toOpaqueUid(uid)] = result;
- return result;
+ return ToCompilerDecl(*result);
}
clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
@@ -494,8 +487,10 @@ clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
if (uid.asCompilandSym().offset == 0)
return FromCompilerDeclContext(GetTranslationUnitDecl());
}
-
- clang::Decl *decl = GetOrCreateDeclForUid(uid);
+ auto option = GetOrCreateDeclForUid(uid);
+ if (!option)
+ return nullptr;
+ clang::Decl *decl = FromCompilerDecl(option.getValue());
if (!decl)
return nullptr;
@@ -1089,7 +1084,7 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
CompilerType param_type_ct(&m_clang, qt.getAsOpaquePtr());
clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
&function_decl, param_name.str().c_str(), param_type_ct,
- clang::SC_None);
+ clang::SC_None, true);
lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
m_uid_to_decl[toOpaqueUid(param_uid)] = param;
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index 67d024741e0d..a4242e90810d 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -51,11 +51,12 @@ struct DeclStatus {
class PdbAstBuilder {
public:
// Constructors and Destructors
- PdbAstBuilder(ObjectFile &obj, PdbIndex &index);
+ PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang);
lldb_private::CompilerDeclContext GetTranslationUnitDecl();
- clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid);
+ llvm::Optional<lldb_private::CompilerDecl>
+ GetOrCreateDeclForUid(PdbSymUid uid);
clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
@@ -76,7 +77,7 @@ public:
CompilerDecl ToCompilerDecl(clang::Decl &decl);
CompilerType ToCompilerType(clang::QualType qt);
CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
- clang::Decl * FromCompilerDecl(CompilerDecl decl);
+ clang::Decl *FromCompilerDecl(CompilerDecl decl);
clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
ClangASTContext &clang() { return m_clang; }
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
index 79dd010ff311..a7bc23519710 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -51,54 +51,23 @@ static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::A
return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
}
-static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program,
- llvm::BumpPtrAllocator &alloc,
- llvm::StringRef &register_name,
- Node *&ast) {
- // lvalue of assignment is always first token
- // rvalue program goes next
- std::tie(register_name, program) = getToken(program);
- if (register_name.empty())
- return false;
-
- ast = Parse(program, alloc);
- return ast != nullptr;
-}
-
-static Node *ParseFPOProgram(llvm::StringRef program,
+static Node *ResolveFPOProgram(llvm::StringRef program,
llvm::StringRef register_name,
llvm::Triple::ArchType arch_type,
llvm::BumpPtrAllocator &alloc) {
- llvm::DenseMap<llvm::StringRef, Node *> dependent_programs;
-
- size_t cur = 0;
- while (true) {
- size_t assign_index = program.find('=', cur);
- if (assign_index == llvm::StringRef::npos) {
- llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos);
- if (!tail.trim().empty()) {
- // missing assign operator
- return nullptr;
- }
- break;
- }
- llvm::StringRef assignment_program = program.slice(cur, assign_index);
-
- llvm::StringRef lvalue_name;
- Node *rvalue_ast = nullptr;
- if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name,
- rvalue_ast)) {
- return nullptr;
- }
-
- lldbassert(rvalue_ast);
+ std::vector<std::pair<llvm::StringRef, Node *>> parsed =
+ postfix::ParseFPOProgram(program, alloc);
+ for (auto it = parsed.begin(), end = parsed.end(); it != end; ++it) {
// Emplace valid dependent subtrees to make target assignment independent
// from predecessors. Resolve all other SymbolNodes as registers.
bool success =
- ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * {
- if (Node *node = dependent_programs.lookup(symbol.GetName()))
- return node;
+ ResolveSymbols(it->second, [&](SymbolNode &symbol) -> Node * {
+ for (const auto &pair : llvm::make_range(parsed.begin(), it)) {
+ if (pair.first == symbol.GetName())
+ return pair.second;
+ }
+
uint32_t reg_num =
ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);
@@ -110,13 +79,10 @@ static Node *ParseFPOProgram(llvm::StringRef program,
if (!success)
return nullptr;
- if (lvalue_name == register_name) {
+ if (it->first == register_name) {
// found target assignment program - no need to parse further
- return rvalue_ast;
+ return it->second;
}
-
- dependent_programs[lvalue_name] = rvalue_ast;
- cur = assign_index + 1;
}
return nullptr;
@@ -127,7 +93,7 @@ bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression(
llvm::Triple::ArchType arch_type, Stream &stream) {
llvm::BumpPtrAllocator node_alloc;
Node *target_program =
- ParseFPOProgram(program, register_name, arch_type, node_alloc);
+ ResolveFPOProgram(program, register_name, arch_type, node_alloc);
if (target_program == nullptr) {
return false;
}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index 1f5c97da81cf..fc047e25a2f4 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -641,14 +641,14 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
llvm::StringRef program;
if (GetFrameDataProgram(index, ranges, program)) {
result.location =
- MakeVFrameRelLocationExpression(program, loc.Offset, module);
+ MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, module);
result.ranges = std::move(ranges);
} else {
// invalid variable
}
} else {
result.location =
- MakeRegRelLocationExpression(base_reg, loc.Offset, module);
+ MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
result.ranges = std::move(ranges);
}
} else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) {
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index e27d4699ae2f..33b8da3b543b 100644
--- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -20,7 +20,6 @@
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -30,6 +29,7 @@
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Utility/Log.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
@@ -90,10 +90,10 @@ static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath,
std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
llvm::StringRef Path = Buffer->getBufferIdentifier();
- auto Stream = llvm::make_unique<llvm::MemoryBufferByteStream>(
+ auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
std::move(Buffer), llvm::support::little);
- auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
+ auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
if (auto EC = File->parseFileHeaders()) {
llvm::consumeError(std::move(EC));
return nullptr;
@@ -119,6 +119,8 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
}
OwningBinary<Binary> binary = std::move(*expected_binary);
+ // TODO: Avoid opening the PE/COFF binary twice by reading this information
+ // directly from the lldb_private::ObjectFile.
auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
if (!obj)
return nullptr;
@@ -264,27 +266,27 @@ const char *SymbolFileNativePDB::GetPluginDescriptionStatic() {
return "Microsoft PDB debug symbol cross-platform file reader.";
}
-SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileNativePDB(obj_file);
+SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileNativePDB(std::move(objfile_sp));
}
-SymbolFileNativePDB::SymbolFileNativePDB(ObjectFile *object_file)
- : SymbolFile(object_file) {}
+SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)) {}
SymbolFileNativePDB::~SymbolFileNativePDB() {}
uint32_t SymbolFileNativePDB::CalculateAbilities() {
uint32_t abilities = 0;
- if (!m_obj_file)
+ if (!m_objfile_sp)
return 0;
if (!m_index) {
// Lazily load and match the PDB file, but only do this once.
std::unique_ptr<PDBFile> file_up =
- loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator);
+ loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), m_allocator);
if (!file_up) {
- auto module_sp = m_obj_file->GetModule();
+ auto module_sp = m_objfile_sp->GetModule();
if (!module_sp)
return 0;
// See if any symbol file is specified through `--symfile` option.
@@ -317,19 +319,24 @@ uint32_t SymbolFileNativePDB::CalculateAbilities() {
}
void SymbolFileNativePDB::InitializeObject() {
- m_obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
+ m_obj_load_address = m_objfile_sp->GetBaseAddress().GetFileAddress();
m_index->SetLoadAddress(m_obj_load_address);
m_index->ParseSectionContribs();
- TypeSystem *ts = m_obj_file->GetModule()->GetTypeSystemForLanguage(
+ auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
lldb::eLanguageTypeC_plus_plus);
- if (ts)
- ts->SetSymbolFile(this);
-
- m_ast = llvm::make_unique<PdbAstBuilder>(*m_obj_file, *m_index);
+ if (auto err = ts_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Failed to initialize");
+ } else {
+ ts_or_err->SetSymbolFile(this);
+ auto *clang = llvm::cast_or_null<ClangASTContext>(&ts_or_err.get());
+ lldbassert(clang);
+ m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang);
+ }
}
-uint32_t SymbolFileNativePDB::GetNumCompileUnits() {
+uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
const DbiModuleList &modules = m_index->dbi().modules();
uint32_t count = modules.getModuleCount();
if (count == 0)
@@ -430,11 +437,10 @@ SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
FileSpec fs(source_file_name);
CompUnitSP cu_sp =
- std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, fs,
+ std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs,
toOpaqueUid(cci.m_id), lang, optimized);
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cci.m_id.modi, cu_sp);
+ SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
return cu_sp;
}
@@ -730,7 +736,7 @@ TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
TypeSP type = CreateAndCacheType(type_id);
if (type)
- m_obj_file->GetModule()->GetTypeList()->Insert(type);
+ GetTypeList().Insert(type);
return type;
}
@@ -900,6 +906,7 @@ lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
}
lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid uid(comp_unit.GetID());
lldbassert(uid.kind() == PdbSymUidKind::Compiland);
@@ -915,6 +922,7 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid uid{comp_unit.GetID()};
lldbassert(uid.kind() == PdbSymUidKind::Compiland);
uint16_t modi = uid.asCompiland().modi;
@@ -948,6 +956,7 @@ static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
uint32_t SymbolFileNativePDB::ResolveSymbolContext(
const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
lldb::addr_t file_addr = addr.GetFileAddress();
@@ -1052,12 +1061,13 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
// all at once, even if all it really needs is line info for a specific
// function. In the future it would be nice if it could set the sc.m_function
// member, and we could only get the line info for the function in question.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid cu_id(comp_unit.GetID());
lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
CompilandIndexItem *cci =
m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
lldbassert(cci);
- auto line_table = llvm::make_unique<LineTable>(&comp_unit);
+ auto line_table = std::make_unique<LineTable>(&comp_unit);
// This is basically a copy of the .debug$S subsections from all original COFF
// object files merged together with address relocations applied. We are
@@ -1130,6 +1140,7 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid cu_id(comp_unit.GetID());
lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
CompilandIndexItem *cci =
@@ -1160,6 +1171,7 @@ bool SymbolFileNativePDB::ParseImportedModules(
}
size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym());
// FIXME: Parse child blocks
return 1;
@@ -1167,9 +1179,10 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
-uint32_t SymbolFileNativePDB::FindGlobalVariables(
+void SymbolFileNativePDB::FindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
@@ -1191,16 +1204,16 @@ uint32_t SymbolFileNativePDB::FindGlobalVariables(
continue;
}
}
- return variables.GetSize();
}
-uint32_t SymbolFileNativePDB::FindFunctions(
+void SymbolFileNativePDB::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// For now we only support lookup by method name.
if (!(name_type_mask & eFunctionNameTypeMethod))
- return 0;
+ return;
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
@@ -1225,45 +1238,34 @@ uint32_t SymbolFileNativePDB::FindFunctions(
sc_list.Append(sc);
}
-
- return sc_list.GetSize();
}
-uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
- return 0;
-}
+void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {}
-uint32_t SymbolFileNativePDB::FindTypes(
+void SymbolFileNativePDB::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- if (!append)
- types.Clear();
+ uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!name)
- return 0;
+ return;
searched_symbol_files.clear();
searched_symbol_files.insert(this);
// There is an assumption 'name' is not a regex
- size_t match_count = FindTypesByName(name.GetStringRef(), max_matches, types);
-
- return match_count;
+ FindTypesByName(name.GetStringRef(), max_matches, types);
}
-size_t
-SymbolFileNativePDB::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- return 0;
-}
+void SymbolFileNativePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {}
-size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
- uint32_t max_matches,
- TypeMap &types) {
+void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
+ uint32_t max_matches,
+ TypeMap &types) {
- size_t match_count = 0;
std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
if (max_matches > 0 && max_matches < matches.size())
matches.resize(max_matches);
@@ -1274,17 +1276,16 @@ size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
continue;
types.Insert(type);
- ++match_count;
}
- return match_count;
}
size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Only do the full type scan the first time.
if (m_done_full_type_scan)
return 0;
- size_t old_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+ const size_t old_count = GetTypeList().GetSize();
LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
// First process the entire TPI stream.
@@ -1314,7 +1315,7 @@ size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
GetOrCreateTypedef(global);
}
- size_t new_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+ const size_t new_count = GetTypeList().GetSize();
m_done_full_type_scan = true;
@@ -1476,6 +1477,7 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
}
size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
lldbassert(sc.function || sc.comp_unit);
VariableListSP variables;
@@ -1506,9 +1508,10 @@ size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
}
CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
- clang::Decl *decl = m_ast->GetOrCreateDeclForUid(PdbSymUid(uid));
-
- return m_ast->ToCompilerDecl(*decl);
+ if (auto decl = m_ast->GetOrCreateDeclForUid(uid))
+ return decl.getValue();
+ else
+ return CompilerDecl();
}
CompilerDeclContext
@@ -1528,6 +1531,7 @@ SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
}
Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto iter = m_types.find(type_uid);
// lldb should not be passing us non-sensical type uids. the only way it
// could have a type uid in the first place is if we handed it out, in which
@@ -1561,11 +1565,9 @@ bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
return m_ast->CompleteType(qt);
}
-size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
- return 0;
-}
+void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {}
CompilerDeclContext
SymbolFileNativePDB::FindNamespace(ConstString name,
@@ -1573,13 +1575,14 @@ SymbolFileNativePDB::FindNamespace(ConstString name,
return {};
}
-TypeSystem *
+llvm::Expected<TypeSystem &>
SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
- auto type_system =
- m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
+ }
+ return type_system_or_err;
}
ConstString SymbolFileNativePDB::GetPluginName() {
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 20daff219a0a..ca7de0e7d1ed 100644
--- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -9,7 +9,6 @@
#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/SymbolFile.h"
#include "llvm/ADT/DenseMap.h"
@@ -35,7 +34,6 @@ struct UnionRecord;
} // namespace llvm
namespace lldb_private {
-class ClangASTImporter;
namespace npdb {
class PdbAstBuilder;
@@ -55,10 +53,10 @@ public:
static const char *GetPluginDescriptionStatic();
- static SymbolFile *CreateInstance(ObjectFile *obj_file);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFileNativePDB(ObjectFile *ofile);
+ SymbolFileNativePDB(lldb::ObjectFileSP objfile_sp);
~SymbolFileNativePDB() override;
@@ -68,13 +66,9 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
void
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -94,10 +88,10 @@ public:
size_t ParseBlocksRecursive(Function &func) override;
- uint32_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t max_matches,
- VariableList &variables) override;
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override;
size_t ParseVariablesForContext(const SymbolContext &sc) override;
@@ -120,28 +114,27 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
- size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
- TypeList &type_list) override;
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override;
- uint32_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) override;
+ void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
- bool append, SymbolContextList &sc_list) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
- uint32_t FindTypes(ConstString name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
- size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
- TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ TypeMap &types) override;
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
CompilerDeclContext
FindNamespace(ConstString name,
@@ -157,9 +150,12 @@ public:
void DumpClangAST(Stream &s) override;
private:
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- size_t FindTypesByName(llvm::StringRef name, uint32_t max_matches,
- TypeMap &types);
+ void FindTypesByName(llvm::StringRef name, uint32_t max_matches,
+ TypeMap &types);
lldb::TypeSP CreateModifierType(PdbTypeSymId type_id,
const llvm::codeview::ModifierRecord &mr,
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 82cfcfbb040f..47c4ad088494 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -120,24 +120,31 @@ GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
return clang_ast.GetBasicType(eBasicTypeBool);
case PDB_BuiltinType::Long:
if (width == ast->getTypeSize(ast->LongTy))
- return CompilerType(ast, ast->LongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->LongTy.getAsOpaquePtr());
if (width == ast->getTypeSize(ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->LongLongTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::ULong:
if (width == ast->getTypeSize(ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->UnsignedLongTy.getAsOpaquePtr());
if (width == ast->getTypeSize(ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->UnsignedLongLongTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::WCharT:
if (width == ast->getTypeSize(ast->WCharTy))
- return CompilerType(ast, ast->WCharTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->WCharTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::Char16:
- return CompilerType(ast, ast->Char16Ty);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->Char16Ty.getAsOpaquePtr());
case PDB_BuiltinType::Char32:
- return CompilerType(ast, ast->Char32Ty);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->Char32Ty.getAsOpaquePtr());
case PDB_BuiltinType::Float:
// Note: types `long double` and `double` have same bit size in MSVC and
// there is no information in the PDB to distinguish them. So when falling
@@ -940,7 +947,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
decl, nullptr, arg_type->GetForwardCompilerType(),
- clang::SC_None);
+ clang::SC_None, true);
if (param)
params.push_back(param);
}
diff --git a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 1c17bf6563b3..42bf1b34c956 100644
--- a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -174,7 +174,7 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ DWARFExpression result(module, extractor, nullptr);
result.SetRegisterKind(register_kind);
return result;
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 17dfcdaceb9c..854e735b5f83 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -24,6 +24,7 @@
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/Variable.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
@@ -118,29 +119,28 @@ const char *SymbolFilePDB::GetPluginDescriptionStatic() {
}
lldb_private::SymbolFile *
-SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
- return new SymbolFilePDB(obj_file);
+SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFilePDB(std::move(objfile_sp));
}
-SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
- : SymbolFile(object_file), m_session_up(), m_global_scope_up(),
- m_cached_compile_unit_count(0) {}
+SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {}
SymbolFilePDB::~SymbolFilePDB() {}
uint32_t SymbolFilePDB::CalculateAbilities() {
uint32_t abilities = 0;
- if (!m_obj_file)
+ if (!m_objfile_sp)
return 0;
if (!m_session_up) {
// Lazily load and match the PDB file, but only do this once.
- std::string exePath = m_obj_file->GetFileSpec().GetPath();
+ std::string exePath = m_objfile_sp->GetFileSpec().GetPath();
auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
m_session_up);
if (error) {
llvm::consumeError(std::move(error));
- auto module_sp = m_obj_file->GetModule();
+ auto module_sp = m_objfile_sp->GetModule();
if (!module_sp)
return 0;
// See if any symbol file is specified through `--symfile` option.
@@ -183,7 +183,8 @@ uint32_t SymbolFilePDB::CalculateAbilities() {
}
void SymbolFilePDB::InitializeObject() {
- lldb::addr_t obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
+ lldb::addr_t obj_load_address =
+ m_objfile_sp->GetBaseAddress().GetFileAddress();
lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);
m_session_up->setLoadAddress(obj_load_address);
if (!m_global_scope_up)
@@ -191,33 +192,30 @@ void SymbolFilePDB::InitializeObject() {
lldbassert(m_global_scope_up.get());
}
-uint32_t SymbolFilePDB::GetNumCompileUnits() {
- if (m_cached_compile_unit_count == 0) {
- auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
- if (!compilands)
- return 0;
+uint32_t SymbolFilePDB::CalculateNumCompileUnits() {
+ auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
+ if (!compilands)
+ return 0;
- // The linker could link *.dll (compiland language = LINK), or import
- // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
- // found as a child of the global scope (PDB executable). Usually, such
- // compilands contain `thunk` symbols in which we are not interested for
- // now. However we still count them in the compiland list. If we perform
- // any compiland related activity, like finding symbols through
- // llvm::pdb::IPDBSession methods, such compilands will all be searched
- // automatically no matter whether we include them or not.
- m_cached_compile_unit_count = compilands->getChildCount();
-
- // The linker can inject an additional "dummy" compilation unit into the
- // PDB. Ignore this special compile unit for our purposes, if it is there.
- // It is always the last one.
- auto last_compiland_up =
- compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
- lldbassert(last_compiland_up.get());
- std::string name = last_compiland_up->getName();
- if (name == "* Linker *")
- --m_cached_compile_unit_count;
- }
- return m_cached_compile_unit_count;
+ // The linker could link *.dll (compiland language = LINK), or import
+ // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
+ // found as a child of the global scope (PDB executable). Usually, such
+ // compilands contain `thunk` symbols in which we are not interested for
+ // now. However we still count them in the compiland list. If we perform
+ // any compiland related activity, like finding symbols through
+ // llvm::pdb::IPDBSession methods, such compilands will all be searched
+ // automatically no matter whether we include them or not.
+ uint32_t compile_unit_count = compilands->getChildCount();
+
+ // The linker can inject an additional "dummy" compilation unit into the
+ // PDB. Ignore this special compile unit for our purposes, if it is there.
+ // It is always the last one.
+ auto last_compiland_up = compilands->getChildAtIndex(compile_unit_count - 1);
+ lldbassert(last_compiland_up.get());
+ std::string name = last_compiland_up->getName();
+ if (name == "* Linker *")
+ --compile_unit_count;
+ return compile_unit_count;
}
void SymbolFilePDB::GetCompileUnitIndex(
@@ -261,6 +259,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
}
lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return lldb::eLanguageTypeUnknown;
@@ -302,11 +301,15 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
comp_unit.AddFunction(func_sp);
LanguageType lang = ParseLanguage(comp_unit);
- TypeSystem *type_system = GetTypeSystemForLanguage(lang);
- if (!type_system)
+ auto type_system_or_err = GetTypeSystemForLanguage(lang);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse PDBFunc");
return nullptr;
+ }
+
ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
@@ -315,6 +318,7 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
}
size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t func_added = 0;
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
@@ -333,6 +337,7 @@ size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (comp_unit.GetLineTable())
return true;
return ParseCompileUnitLineTable(comp_unit, 0);
@@ -351,6 +356,7 @@ bool SymbolFilePDB::ParseSupportFiles(
// second time seems like a waste. Unfortunately, there's no good way around
// this short of a moderate refactor since SymbolVendor depends on being able
// to cache this list.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return false;
@@ -428,6 +434,7 @@ static size_t ParseFunctionBlocksForPDBSymbol(
}
size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
auto uid = func.GetID();
auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
@@ -440,6 +447,7 @@ size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
auto compiland = GetPDBCompilandByUID(comp_unit.GetID());
@@ -492,6 +500,7 @@ size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
size_t
SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!sc.comp_unit)
return 0;
@@ -540,14 +549,21 @@ SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
}
lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto find_result = m_types.find(type_uid);
if (find_result != m_types.end())
return find_result->second.get();
- TypeSystem *type_system =
+ auto type_system_or_err =
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to ResolveTypeUID");
+ return nullptr;
+ }
+
ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
PDBASTParser *pdb = clang_type_system->GetPDBParser();
@@ -561,9 +577,7 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
if (result) {
m_types.insert(std::make_pair(type_uid, result));
- auto type_list = GetTypeList();
- if (type_list)
- type_list->Insert(result);
+ GetTypeList().Insert(result);
}
return result.get();
}
@@ -577,8 +591,17 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
std::lock_guard<std::recursive_mutex> guard(
GetObjectFile()->GetModule()->GetMutex());
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get dynamic array info for UID");
+ return false;
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+
if (!clang_ast_ctx)
return false;
@@ -590,8 +613,16 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
}
lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get decl for UID");
+ return CompilerDecl();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDecl();
@@ -612,8 +643,16 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DeclContext for UID");
+ return CompilerDeclContext();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -634,8 +673,16 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DeclContext containing UID");
+ return CompilerDeclContext();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -655,8 +702,16 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
void SymbolFilePDB::ParseDeclsForContext(
lldb_private::CompilerDeclContext decl_ctx) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse decls for context");
+ return;
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return;
@@ -672,6 +727,7 @@ uint32_t
SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextCompUnit ||
resolve_scope & eSymbolContextVariable ||
@@ -680,7 +736,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
resolve_scope & eSymbolContextLineEntry) {
auto cu_sp = GetCompileUnitContainsAddress(so_addr);
if (!cu_sp) {
- if (resolved_flags | eSymbolContextVariable) {
+ if (resolved_flags & eSymbolContextVariable) {
// TODO: Resolve variables
}
return 0;
@@ -732,6 +788,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
uint32_t SymbolFilePDB::ResolveSymbolContext(
const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const size_t old_size = sc_list.GetSize();
if (resolve_scope & lldb::eSymbolContextCompUnit) {
// Locate all compilation units with line numbers referencing the specified
@@ -1040,18 +1097,19 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
return num_added;
}
-uint32_t SymbolFilePDB::FindGlobalVariables(
+void SymbolFilePDB::FindGlobalVariables(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, lldb_private::VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
if (name.IsEmpty())
- return 0;
+ return;
auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (!results)
- return 0;
+ return;
uint32_t matches = 0;
size_t old_size = variables.GetSize();
@@ -1061,7 +1119,7 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
break;
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
lldbassert(sc.module_sp.get());
if (!name.GetStringRef().equals(
@@ -1080,19 +1138,17 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
ParseVariables(sc, *pdb_data, &variables);
matches = variables.GetSize() - old_size;
}
-
- return matches;
}
-uint32_t
-SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) {
+void SymbolFilePDB::FindGlobalVariables(
+ const lldb_private::RegularExpression &regex, uint32_t max_matches,
+ lldb_private::VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!regex.IsValid())
- return 0;
+ return;
auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (!results)
- return 0;
+ return;
uint32_t matches = 0;
size_t old_size = variables.GetSize();
@@ -1106,7 +1162,7 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
if (!regex.Execute(var_name))
continue;
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
lldbassert(sc.module_sp.get());
sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
@@ -1117,8 +1173,6 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
ParseVariables(sc, *pdb_data, &variables);
matches = variables.GetSize() - old_size;
}
-
- return matches;
}
bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
@@ -1240,23 +1294,21 @@ void SymbolFilePDB::CacheFunctionNames() {
m_func_base_names.SizeToFit();
}
-uint32_t SymbolFilePDB::FindFunctions(
+void SymbolFilePDB::FindFunctions(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
lldb_private::SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);
if (name_type_mask == eFunctionNameTypeNone)
- return 0;
+ return;
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
if (name.IsEmpty())
- return 0;
+ return;
- auto old_size = sc_list.GetSize();
if (name_type_mask & eFunctionNameTypeFull ||
name_type_mask & eFunctionNameTypeBase ||
name_type_mask & eFunctionNameTypeMethod) {
@@ -1286,26 +1338,20 @@ uint32_t SymbolFilePDB::FindFunctions(
ResolveFn(m_func_base_names);
ResolveFn(m_func_method_names);
}
- if (name_type_mask & eFunctionNameTypeBase) {
+ if (name_type_mask & eFunctionNameTypeBase)
ResolveFn(m_func_base_names);
- }
- if (name_type_mask & eFunctionNameTypeMethod) {
+ if (name_type_mask & eFunctionNameTypeMethod)
ResolveFn(m_func_method_names);
- }
}
- return sc_list.GetSize() - old_size;
}
-uint32_t
-SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
+void SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!regex.IsValid())
- return 0;
+ return;
- auto old_size = sc_list.GetSize();
CacheFunctionNames();
std::set<uint32_t> resolved_ids;
@@ -1322,8 +1368,6 @@ SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
};
ResolveFn(m_func_full_names);
ResolveFn(m_func_base_names);
-
- return sc_list.GetSize() - old_size;
}
void SymbolFilePDB::GetMangledNamesForFunction(
@@ -1339,7 +1383,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
if (!results)
return;
- auto section_list = m_obj_file->GetSectionList();
+ auto section_list = m_objfile_sp->GetSectionList();
if (!section_list)
return;
@@ -1361,7 +1405,6 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.AddSymbol(
Symbol(pub_symbol->getSymIndexId(), // symID
pub_symbol->getName().c_str(), // name
- true, // name_is_mangled
pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type
true, // external
false, // is_debug
@@ -1380,34 +1423,39 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.Finalize();
}
-uint32_t SymbolFilePDB::FindTypes(
+void SymbolFilePDB::FindTypes(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) {
- if (!append)
- types.Clear();
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!name)
- return 0;
+ return;
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ 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);
-
- return types.GetSize();
}
void SymbolFilePDB::DumpClangAST(Stream &s) {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- if (!clang)
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to dump ClangAST");
+ return;
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ if (!clang_type_system)
return;
- clang->Dump(s);
+ clang_type_system->Dump(s);
}
void SymbolFilePDB::FindTypesByRegex(
@@ -1514,15 +1562,9 @@ void SymbolFilePDB::FindTypesByName(
}
}
-size_t SymbolFilePDB::FindTypes(
- const std::vector<lldb_private::CompilerContext> &contexts, bool append,
- lldb_private::TypeMap &types) {
- return 0;
-}
-
-lldb_private::TypeList *SymbolFilePDB::GetTypeList() {
- return m_obj_file->GetModule()->GetTypeList();
-}
+void SymbolFilePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages,
+ lldb_private::TypeMap &types) {}
void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
uint32_t type_mask,
@@ -1574,17 +1616,17 @@ void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
}
-size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
+void SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
TypeCollection type_collection;
- uint32_t old_size = type_list.GetSize();
CompileUnit *cu =
sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
if (cu) {
auto compiland_up = GetPDBCompilandByUID(cu->GetID());
if (!compiland_up)
- return 0;
+ return;
GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
} else {
for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
@@ -1600,21 +1642,29 @@ size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
type->GetForwardCompilerType();
type_list.Insert(type->shared_from_this());
}
- return type_list.GetSize() - old_size;
}
-lldb_private::TypeSystem *
+llvm::Expected<lldb_private::TypeSystem &>
SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
- auto type_system =
- m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
+ }
+ return type_system_or_err;
}
PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get PDB AST parser");
+ return nullptr;
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
@@ -1625,8 +1675,18 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to find namespace {}",
+ name.AsCString());
+ return CompilerDeclContext();
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return CompilerDeclContext();
@@ -1644,7 +1704,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
if (!namespace_decl)
return CompilerDeclContext();
- return CompilerDeclContext(type_system,
+ return CompilerDeclContext(clang_type_system,
static_cast<clang::DeclContext *>(namespace_decl));
}
@@ -1688,7 +1748,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
// Don't support optimized code for now, DebugInfoPDB does not return this
// information.
LazyBool optimized = eLazyBoolNo;
- auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
+ auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
path.c_str(), id, lang, optimized);
if (!cu_sp)
@@ -1698,8 +1758,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
if (index == UINT32_MAX)
GetCompileUnitIndex(*compiland_up, index);
lldbassert(index != UINT32_MAX);
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(index,
- cu_sp);
+ SetCompileUnitAtIndex(index, cu_sp);
return cu_sp;
}
@@ -1715,7 +1774,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
// to do a mapping so that we can hand out indices.
llvm::DenseMap<uint32_t, uint32_t> index_map;
BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
- auto line_table = llvm::make_unique<LineTable>(&comp_unit);
+ auto line_table = std::make_unique<LineTable>(&comp_unit);
// Find contributions to `compiland` from all source and header files.
std::string path = comp_unit.GetPath();
@@ -1925,9 +1984,17 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
if (!decl_ctx_type_system)
return false;
- TypeSystem *type_system = GetTypeSystemForLanguage(
+ auto type_system_or_err = GetTypeSystemForLanguage(
decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err),
+ "Unable to determine if DeclContext matches this symbol file");
+ return false;
+ }
+
+ if (decl_ctx_type_system == &type_system_or_err.get())
return true; // The type systems match, return true
return false;
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index ba3099aaec4d..df717bbbbdb0 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -35,10 +35,10 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFilePDB(lldb_private::ObjectFile *ofile);
+ SymbolFilePDB(lldb::ObjectFileSP objfile_sp);
~SymbolFilePDB() override;
@@ -48,10 +48,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -103,25 +99,25 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
void GetMangledNamesForFunction(
const std::string &scope_qualified_name,
@@ -129,26 +125,25 @@ public:
void AddSymbols(lldb_private::Symtab &symtab) override;
- uint32_t
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
- size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
- bool append, lldb_private::TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
+ lldb_private::LanguageSet languages,
+ lldb_private::TypeMap &types) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
uint32_t max_matches, lldb_private::TypeMap &types);
- lldb_private::TypeList *GetTypeList() override;
-
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
@@ -173,6 +168,10 @@ private:
};
using SecContribsMap = std::map<uint32_t, std::vector<SecContribInfo>>;
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id,
uint32_t index = UINT32_MAX);
@@ -245,7 +244,6 @@ private:
std::vector<lldb::TypeSP> m_builtin_types;
std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
std::unique_ptr<llvm::pdb::PDBSymbolExe> m_global_scope_up;
- uint32_t m_cached_compile_unit_count;
lldb_private::UniqueCStringMap<uint32_t> m_func_full_names;
lldb_private::UniqueCStringMap<uint32_t> m_func_base_names;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index a1b21e51b0fe..62da76581c3e 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -43,26 +43,24 @@ const char *SymbolFileSymtab::GetPluginDescriptionStatic() {
return "Reads debug symbols from an object file's symbol table.";
}
-SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileSymtab(obj_file);
+SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileSymtab(std::move(objfile_sp));
}
-size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
- return 0;
-}
+void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {}
-SymbolFileSymtab::SymbolFileSymtab(ObjectFile *obj_file)
- : SymbolFile(obj_file), m_source_indexes(), m_func_indexes(),
+SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(),
m_code_indexes(), m_objc_class_name_to_index() {}
SymbolFileSymtab::~SymbolFileSymtab() {}
uint32_t SymbolFileSymtab::CalculateAbilities() {
uint32_t abilities = 0;
- if (m_obj_file) {
- const Symtab *symtab = m_obj_file->GetSymtab();
+ if (m_objfile_sp) {
+ const Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
// The snippet of code below will get the indexes the module symbol table
// entries that are code, data, or function related (debug info), sort
@@ -104,7 +102,7 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
return abilities;
}
-uint32_t SymbolFileSymtab::GetNumCompileUnits() {
+uint32_t SymbolFileSymtab::CalculateNumCompileUnits() {
// If we don't have any source file symbols we will just have one compile
// unit for the entire object file
if (m_source_indexes.empty())
@@ -122,10 +120,10 @@ CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
// unit for the entire object file
if (idx < m_source_indexes.size()) {
const Symbol *cu_symbol =
- m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
+ m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
- cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
- cu_symbol->GetName().AsCString(), 0,
+ cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
+ cu_symbol->GetName().AsCString(), 0,
eLanguageTypeUnknown, eLazyBoolNo);
}
return cu_sp;
@@ -136,12 +134,13 @@ lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
// We must at least have a valid compile unit
- const Symtab *symtab = m_obj_file->GetSymtab();
+ const Symtab *symtab = m_objfile_sp->GetSymtab();
const Symbol *curr_symbol = nullptr;
const Symbol *next_symbol = nullptr;
- // const char *prefix = m_obj_file->SymbolPrefix();
+ // const char *prefix = m_objfile_sp->SymbolPrefix();
// if (prefix == NULL)
// prefix == "";
//
@@ -246,12 +245,13 @@ bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
- if (m_obj_file->GetSymtab() == nullptr)
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (m_objfile_sp->GetSymtab() == nullptr)
return 0;
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextSymbol) {
- sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(
+ sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
so_addr.GetFileAddress());
if (sc.symbol)
resolved_flags |= eSymbolContextSymbol;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index bc9a531419ae..2ac4660f0125 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -18,7 +18,7 @@
class SymbolFileSymtab : public lldb_private::SymbolFile {
public:
// Constructors and Destructors
- SymbolFileSymtab(lldb_private::ObjectFile *obj_file);
+ SymbolFileSymtab(lldb::ObjectFileSP objfile_sp);
~SymbolFileSymtab() override;
@@ -32,15 +32,11 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
uint32_t CalculateAbilities() override;
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -75,9 +71,9 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
// PluginInterface protocol
lldb_private::ConstString GetPluginName() override;
@@ -85,6 +81,10 @@ public:
uint32_t GetPluginVersion() override;
protected:
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
lldb_private::Symtab::IndexCollection m_source_indexes;
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index f279af61a131..e61e5763fabb 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -10,6 +10,7 @@
#include <string.h>
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -61,99 +62,86 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
if (!module_sp)
return nullptr;
- ObjectFile *obj_file = module_sp->GetObjectFile();
+ ObjectFileELF *obj_file =
+ llvm::dyn_cast_or_null<ObjectFileELF>(module_sp->GetObjectFile());
if (!obj_file)
return nullptr;
- static ConstString obj_file_elf("elf");
- ConstString obj_name = obj_file->GetPluginName();
- if (obj_name != obj_file_elf)
- return nullptr;
-
lldb_private::UUID uuid = obj_file->GetUUID();
if (!uuid)
return nullptr;
- // Get the .gnu_debuglink file (if specified).
- FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
-
- // If the module specified a filespec, use it first.
- FileSpec debug_symbol_fspec(module_sp->GetSymbolFileFileSpec());
- if (debug_symbol_fspec)
- file_spec_list.Insert(0, debug_symbol_fspec);
-
- // If we have no debug symbol files, then nothing to do.
- if (file_spec_list.IsEmpty())
+ // If the main object file already contains debug info, then we are done.
+ if (obj_file->GetSectionList()->FindSectionByType(
+ lldb::eSectionTypeDWARFDebugInfo, true))
return nullptr;
+ // If the module specified a filespec, use that.
+ FileSpec fspec = module_sp->GetSymbolFileFileSpec();
+ // Otherwise, try gnu_debuglink, if one exists.
+ if (!fspec)
+ fspec = obj_file->GetDebugLink().getValueOr(FileSpec());
+
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)",
module_sp->GetFileSpec().GetPath().c_str());
- for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) {
- ModuleSpec module_spec;
- const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
-
- module_spec.GetFileSpec() = obj_file->GetFileSpec();
- FileSystem::Instance().Resolve(module_spec.GetFileSpec());
- module_spec.GetSymbolFileSpec() = fspec;
- module_spec.GetUUID() = uuid;
- FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
- FileSpec dsym_fspec =
- Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
- if (dsym_fspec) {
- DataBufferSP dsym_file_data_sp;
- lldb::offset_t dsym_file_data_offset = 0;
- ObjectFileSP dsym_objfile_sp =
- ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
- FileSystem::Instance().GetByteSize(dsym_fspec),
- dsym_file_data_sp, dsym_file_data_offset);
- if (dsym_objfile_sp) {
- // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
- // be able to figure this out consistently as the symbol file may not
- // have stripped the code sections, etc.
- dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
-
- SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
- if (symbol_vendor) {
- // Get the module unified section list and add our debug sections to
- // that.
- SectionList *module_section_list = module_sp->GetSectionList();
- SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
-
- static const SectionType g_sections[] = {
- eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
- eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
- eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
- eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
- eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
- eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
- eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink,
- };
- for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
- ++idx) {
- SectionType section_type = g_sections[idx];
- SectionSP section_sp(
- objfile_section_list->FindSectionByType(section_type, true));
- if (section_sp) {
- SectionSP module_section_sp(
- module_section_list->FindSectionByType(section_type, true));
- if (module_section_sp)
- module_section_list->ReplaceSection(module_section_sp->GetID(),
- section_sp);
- else
- module_section_list->AddSection(section_sp);
- }
- }
-
- symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
- return symbol_vendor;
- }
- }
+ ModuleSpec module_spec;
+
+ module_spec.GetFileSpec() = obj_file->GetFileSpec();
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+ module_spec.GetSymbolFileSpec() = fspec;
+ module_spec.GetUUID() = uuid;
+ FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
+ FileSpec dsym_fspec =
+ Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+ if (!dsym_fspec)
+ return nullptr;
+
+ DataBufferSP dsym_file_data_sp;
+ lldb::offset_t dsym_file_data_offset = 0;
+ ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
+ module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
+ dsym_file_data_sp, dsym_file_data_offset);
+ if (!dsym_objfile_sp)
+ return nullptr;
+
+ // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
+ // be able to figure this out consistently as the symbol file may not
+ // have stripped the code sections, etc.
+ dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
+
+ SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
+
+ // Get the module unified section list and add our debug sections to
+ // that.
+ SectionList *module_section_list = module_sp->GetSectionList();
+ SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
+
+ static const SectionType g_sections[] = {
+ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
+ eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
+ eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
+ eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
+ eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
+ eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
+ eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
+ eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink,
+ };
+ for (SectionType section_type : g_sections) {
+ if (SectionSP section_sp =
+ objfile_section_list->FindSectionByType(section_type, true)) {
+ if (SectionSP module_section_sp =
+ module_section_list->FindSectionByType(section_type, true))
+ module_section_list->ReplaceSection(module_section_sp->GetID(),
+ section_sp);
+ else
+ module_section_list->AddSection(section_sp);
}
}
- return nullptr;
+
+ symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+ return symbol_vendor;
}
// PluginInterface protocol
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 43041ca1bb2f..bf6f60a2d26c 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -1328,6 +1328,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
unwind_plan.SetSourceName("assembly insn profiling");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
@@ -1370,7 +1371,6 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
int row_id = 1;
bool unwind_plan_updated = false;
UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
- m_cur_insn = data + offset;
// After a mid-function epilogue we will need to re-insert the original
// unwind rules so unwinds work for the remainder of the function. These
@@ -1380,19 +1380,17 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
while (offset < size) {
m_cur_insn = data + offset;
int insn_len;
- if (!instruction_length(m_cur_insn, insn_len, size - offset)
- || insn_len == 0
- || insn_len > kMaxInstructionByteSize) {
+ if (!instruction_length(m_cur_insn, insn_len, size - offset) ||
+ insn_len == 0 || insn_len > kMaxInstructionByteSize) {
// An unrecognized/junk instruction.
break;
}
// Advance offsets.
offset += insn_len;
- m_cur_insn = data + offset;
// offset is pointing beyond the bounds of the function; stop looping.
- if (offset >= size)
+ if (offset >= size)
continue;
if (reinstate_unwind_state) {
@@ -1546,16 +1544,18 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
// [0x5d] pop %rbp/%ebp
// => [0xc3] ret
if (pop_rbp_pattern_p() || leave_pattern_p()) {
- offset += 1;
- row->SetOffset(offset);
- row->GetCFAValue().SetIsRegisterPlusOffset(
- first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow(new_row);
- unwind_plan_updated = true;
- reinstate_unwind_state = true;
- continue;
+ m_cur_insn++;
+ if (ret_pattern_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ reinstate_unwind_state = true;
+ continue;
+ }
}
} else {
// CFA register is not sp or fp.